FastHTTP

Go向けの高性能HTTPパッケージ。net/httpの最大10倍の性能を実現する設計。ゼロメモリアロケーション、高度な最適化により極限の性能を追求。大量のリクエスト処理やレイテンシが重要なアプリケーションに特化。

HTTPクライアントGo高パフォーマンスゼロアロケーションコネクションプール

GitHub概要

valyala/fasthttp

Fast HTTP package for Go. Tuned for high performance. Zero memory allocations in hot paths. Up to 10x faster than net/http

スター22,742
ウォッチ391
フォーク1,800
作成日:2015年10月18日
言語:Go
ライセンス:MIT License

トピックス

なし

スター履歴

valyala/fasthttp Star History
データ取得日時: 2025/7/18 01:39

ライブラリ

fasthttp

概要

fasthttpは「Go言語向けの高速HTTPクライアント・サーバーライブラリ」として開発された、標準のnet/httpより最大10倍高速なHTTP通信ライブラリです。「ゼロアロケーション設計」をコンセプトに、メモリ割り当てを極限まで削減し、オブジェクトプールとコネクションプールを活用した最適化により、高負荷環境下での圧倒的なパフォーマンスを実現。企業レベルの大規模Webサービスで1.5M以上の同時接続から毎秒200K以上のリクエストを処理する実績を持ち、Go言語でのHTTP通信における究極のパフォーマンスソリューションとして地位を確立しています。

詳細

fasthttp 2025年版は高負荷HTTP通信における決定版として、標準のnet/httpを大幅に上回る性能を提供し続けています。ゼロアロケーション設計による徹底したメモリ最適化、オブジェクトプールによるGC負荷軽減、効率的なコネクション管理により、レイテンシとスループットの両面で劇的な改善を実現。VertaMediaなどの大手企業で毎秒数十万リクエストの処理実績があり、マイクロサービス、API Gateway、高負荷Webサーバーで威力を発揮します。net/httpとは異なるAPIを採用しているため移行には注意が必要ですが、パフォーマンス重視の場面では圧倒的な優位性を提供します。

主な特徴

  • ゼロアロケーション設計: メモリ割り当てを極限まで削減した最適化
  • オブジェクトプールとコネクションプール: 効率的なリソース再利用システム
  • 超高速処理: net/httpの最大10倍のパフォーマンス実現
  • 大規模対応: 数十万RPS・数百万同時接続の処理能力
  • 柔軟なAPI: レスポンス送信前の任意タイミングでのヘッダー・ボディ設定
  • 包括的な機能: HTTPクライアント・サーバー両方の完全実装

メリット・デメリット

メリット

  • net/httpを大幅に上回る圧倒的なパフォーマンス(最大10倍高速)
  • ゼロアロケーション設計によるメモリ効率とGC負荷軽減
  • 大規模サービスでの実証済み安定性と処理能力
  • オブジェクト・コネクションプールによる効率的なリソース管理
  • 高度なカスタマイズ性とパフォーマンスチューニング機能
  • HTTPクライアント・サーバー両方の包括的機能提供

デメリット

  • net/httpとAPI互換性がなく移行時にコード変更が必要
  • ストリーミング処理がnet/httpより限定的
  • HTTP/2サポートが開発中でまだ完全ではない
  • エコシステムと学習リソースがnet/httpより少ない
  • 適切な最適化なしでは性能向上が期待できない場合がある
  • Go 1.23以降の比較的新しいバージョンが必要

参考ページ

書き方の例

インストールと基本セットアップ

# fasthttpのインストール
go get -u github.com/valyala/fasthttp

# Go環境での確認
go version  # Go 1.23以降が必要

# 基本的なプロジェクト初期化
go mod init fasthttp-example
go get github.com/valyala/fasthttp

基本的なHTTPサーバー実装

package main

import (
	"fmt"
	"log"
	"github.com/valyala/fasthttp"
)

// 基本的なリクエストハンドラー
func requestHandler(ctx *fasthttp.RequestCtx) {
	// リクエスト情報の取得
	fmt.Fprintf(ctx, "Hello, World! リクエストパス: %q\n", ctx.Path())
	fmt.Fprintf(ctx, "リクエストメソッド: %q\n", ctx.Method())
	fmt.Fprintf(ctx, "ユーザーエージェント: %q\n", ctx.UserAgent())
	
	// レスポンスヘッダーの設定
	ctx.SetContentType("text/plain; charset=utf-8")
	ctx.SetStatusCode(fasthttp.StatusOK)
}

// 高度なリクエストハンドラー
func advancedHandler(ctx *fasthttp.RequestCtx) {
	// パスベースのルーティング
	switch string(ctx.Path()) {
	case "/":
		ctx.SetContentType("text/html")
		fmt.Fprintf(ctx, "<h1>ホームページ</h1><p>fasthttp Server</p>")
	case "/api/status":
		ctx.SetContentType("application/json")
		fmt.Fprintf(ctx, `{"status": "ok", "server": "fasthttp"}`)
	case "/api/headers":
		ctx.SetContentType("application/json")
		fmt.Fprintf(ctx, `{"headers": {`)
		ctx.Request.Header.VisitAll(func(key, value []byte) {
			fmt.Fprintf(ctx, `"%s": "%s",`, string(key), string(value))
		})
		fmt.Fprintf(ctx, `}}`)
	default:
		ctx.Error("見つかりません", fasthttp.StatusNotFound)
	}
}

// 構造体ベースのハンドラー
type MyHandler struct {
	name string
}

func (h *MyHandler) HandleFastHTTP(ctx *fasthttp.RequestCtx) {
	fmt.Fprintf(ctx, "Handler名: %s\n", h.name)
	fmt.Fprintf(ctx, "リクエストURI: %q", ctx.RequestURI())
}

func main() {
	// 基本サーバー起動
	log.Println("fasthttpサーバーを :8080 で起動中...")
	log.Fatal(fasthttp.ListenAndServe(":8080", requestHandler))
	
	// 高度なサーバー設定
	server := &fasthttp.Server{
		Handler:          advancedHandler,
		ReadTimeout:      time.Second * 30,
		WriteTimeout:     time.Second * 30,
		IdleTimeout:      time.Second * 60,
		MaxConnsPerIP:    1000,
		MaxRequestsPerConn: 1000,
		MaxRequestBodySize: 1024 * 1024, // 1MB
	}
	
	log.Println("カスタムサーバーを :8081 で起動中...")
	log.Fatal(server.ListenAndServe(":8081"))
	
	// 構造体ハンドラーの使用
	myHandler := &MyHandler{name: "カスタムハンドラー"}
	log.Fatal(fasthttp.ListenAndServe(":8082", myHandler.HandleFastHTTP))
}

HTTPクライアント実装(GET/POST/PUT/DELETE)

package main

import (
	"fmt"
	"log"
	"time"
	"github.com/valyala/fasthttp"
)

func main() {
	// 基本的なGETリクエスト
	statusCode, body, err := fasthttp.Get(nil, "https://httpbin.org/get")
	if err != nil {
		log.Fatalf("GETリクエストエラー: %v", err)
	}
	fmt.Printf("ステータス: %d\nレスポンス: %s\n", statusCode, body)
	
	// クエリパラメータ付きGETリクエスト
	req := fasthttp.AcquireRequest()
	resp := fasthttp.AcquireResponse()
	defer fasthttp.ReleaseRequest(req)
	defer fasthttp.ReleaseResponse(resp)
	
	req.SetRequestURI("https://httpbin.org/get?page=1&limit=10")
	req.Header.SetMethod(fasthttp.MethodGet)
	req.Header.Set("User-Agent", "fasthttp-client/1.0")
	
	client := &fasthttp.Client{
		ReadTimeout:  time.Second * 30,
		WriteTimeout: time.Second * 30,
	}
	
	err = client.Do(req, resp)
	if err != nil {
		log.Fatalf("リクエストエラー: %v", err)
	}
	
	fmt.Printf("ステータス: %d\n", resp.StatusCode())
	fmt.Printf("レスポンス: %s\n", resp.Body())
	
	// POSTリクエスト(JSON送信)
	req.Reset()
	resp.Reset()
	
	jsonData := `{"name": "田中太郎", "email": "[email protected]", "age": 30}`
	
	req.SetRequestURI("https://httpbin.org/post")
	req.Header.SetMethod(fasthttp.MethodPost)
	req.Header.SetContentType("application/json")
	req.Header.Set("Authorization", "Bearer your-token")
	req.SetBody([]byte(jsonData))
	
	err = client.Do(req, resp)
	if err != nil {
		log.Fatalf("POSTリクエストエラー: %v", err)
	}
	
	fmt.Printf("POST ステータス: %d\n", resp.StatusCode())
	fmt.Printf("POST レスポンス: %s\n", resp.Body())
	
	// PUTリクエスト(データ更新)
	req.Reset()
	resp.Reset()
	
	updateData := `{"name": "田中次郎", "email": "[email protected]"}`
	
	req.SetRequestURI("https://httpbin.org/put")
	req.Header.SetMethod(fasthttp.MethodPut)
	req.Header.SetContentType("application/json")
	req.SetBody([]byte(updateData))
	
	err = client.Do(req, resp)
	if err != nil {
		log.Fatalf("PUTリクエストエラー: %v", err)
	}
	
	fmt.Printf("PUT ステータス: %d\n", resp.StatusCode())
	
	// DELETEリクエスト
	req.Reset()
	resp.Reset()
	
	req.SetRequestURI("https://httpbin.org/delete")
	req.Header.SetMethod(fasthttp.MethodDelete)
	req.Header.Set("Authorization", "Bearer your-token")
	
	err = client.Do(req, resp)
	if err != nil {
		log.Fatalf("DELETEリクエストエラー: %v", err)
	}
	
	fmt.Printf("DELETE ステータス: %d\n", resp.StatusCode())
	
	// HostClientを使用した効率的なリクエスト
	hostClient := &fasthttp.HostClient{
		Addr:         "httpbin.org:443",
		IsTLS:        true,
		MaxConns:     100,
		ReadTimeout:  time.Second * 30,
		WriteTimeout: time.Second * 30,
	}
	
	req.Reset()
	resp.Reset()
	
	req.SetRequestURI("https://httpbin.org/get")
	req.Header.SetMethod(fasthttp.MethodGet)
	
	err = hostClient.Do(req, resp)
	if err != nil {
		log.Fatalf("HostClientリクエストエラー: %v", err)
	}
	
	fmt.Printf("HostClient ステータス: %d\n", resp.StatusCode())
}

高度な設定とカスタマイズ(認証、タイムアウト、プロキシ等)

package main

import (
	"crypto/tls"
	"fmt"
	"log"
	"time"
	"github.com/valyala/fasthttp"
)

func main() {
	// カスタムクライアント設定
	client := &fasthttp.Client{
		// タイムアウト設定
		ReadTimeout:  time.Second * 30,
		WriteTimeout: time.Second * 30,
		MaxIdleConnDuration: time.Minute * 5,
		
		// コネクション制限
		MaxConnsPerHost:     100,
		MaxIdleConnDuration: time.Minute,
		
		// TLS設定
		TLSConfig: &tls.Config{
			InsecureSkipVerify: false, // 本番では true にしない
		},
		
		// リトライ設定
		MaxIdemponentCallAttempts: 3,
	}
	
	req := fasthttp.AcquireRequest()
	resp := fasthttp.AcquireResponse()
	defer fasthttp.ReleaseRequest(req)
	defer fasthttp.ReleaseResponse(resp)
	
	// カスタムヘッダー設定
	req.SetRequestURI("https://httpbin.org/headers")
	req.Header.SetMethod(fasthttp.MethodGet)
	req.Header.Set("User-Agent", "fasthttp-client/1.0")
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Accept-Language", "ja-JP,en-US")
	req.Header.Set("X-API-Version", "v2")
	req.Header.Set("X-Request-ID", "req-12345")
	
	// Basic認証
	req.Header.Set("Authorization", "Basic dXNlcjpwYXNz") // user:pass
	
	err := client.Do(req, resp)
	if err != nil {
		log.Fatalf("認証リクエストエラー: %v", err)
	}
	
	fmt.Printf("認証レスポンス: %s\n", resp.Body())
	
	// プロキシ設定付きクライアント
	proxyClient := &fasthttp.Client{
		Dial: fasthttp.DialDualStackTimeout(time.Second * 30),
		// プロキシはfasthttpでは直接サポートされていないため、
		// カスタムDialer実装またはサードパーティライブラリが必要
	}
	
	// Cookie設定
	req.Reset()
	resp.Reset()
	
	req.SetRequestURI("https://httpbin.org/cookies")
	req.Header.SetMethod(fasthttp.MethodGet)
	req.Header.SetCookie("session_id", "abc123")
	req.Header.SetCookie("user_pref", "dark_mode")
	
	err = client.Do(req, resp)
	if err != nil {
		log.Fatalf("Cookieリクエストエラー: %v", err)
	}
	
	fmt.Printf("Cookie レスポンス: %s\n", resp.Body())
	
	// マルチパートフォームデータ送信
	req.Reset()
	resp.Reset()
	
	req.SetRequestURI("https://httpbin.org/post")
	req.Header.SetMethod(fasthttp.MethodPost)
	req.Header.SetContentType("multipart/form-data; boundary=----formdata")
	
	multipartBody := `------formdata
Content-Disposition: form-data; name="username"

testuser
------formdata
Content-Disposition: form-data; name="password"

secret123
------formdata--`
	
	req.SetBody([]byte(multipartBody))
	
	err = client.Do(req, resp)
	if err != nil {
		log.Fatalf("マルチパートリクエストエラー: %v", err)
	}
	
	fmt.Printf("マルチパート ステータス: %d\n", resp.StatusCode())
	
	// ストリーミング対応の大きなファイル処理
	req.Reset()
	resp.Reset()
	
	req.SetRequestURI("https://httpbin.org/stream/100")
	req.Header.SetMethod(fasthttp.MethodGet)
	
	err = client.Do(req, resp)
	if err != nil {
		log.Fatalf("ストリーミングリクエストエラー: %v", err)
	}
	
	// レスポンスの段階的処理
	bodyBytes := resp.Body()
	fmt.Printf("ストリーミングデータサイズ: %d bytes\n", len(bodyBytes))
	
	// カスタムHostClient(特定ホスト専用)
	hostClient := &fasthttp.HostClient{
		Addr:         "httpbin.org:443",
		IsTLS:        true,
		MaxConns:     50,
		ReadTimeout:  time.Second * 15,
		WriteTimeout: time.Second * 15,
		
		// Keep-Alive設定
		MaxIdleConnDuration: time.Minute * 5,
		
		// カスタムTLS設定
		TLSConfig: &tls.Config{
			ServerName: "httpbin.org",
			MinVersion: tls.VersionTLS12,
		},
	}
	
	req.Reset()
	resp.Reset()
	
	req.SetRequestURI("https://httpbin.org/get")
	req.Header.SetMethod(fasthttp.MethodGet)
	
	err = hostClient.Do(req, resp)
	if err != nil {
		log.Fatalf("HostClientエラー: %v", err)
	}
	
	fmt.Printf("HostClient ステータス: %d\n", resp.StatusCode())
}

エラーハンドリングとリトライ機能

package main

import (
	"fmt"
	"log"
	"time"
	"github.com/valyala/fasthttp"
)

// カスタムエラータイプ
type HTTPError struct {
	StatusCode int
	Message    string
	URL        string
}

func (e *HTTPError) Error() string {
	return fmt.Sprintf("HTTP %d: %s (URL: %s)", e.StatusCode, e.Message, e.URL)
}

// 安全なリクエスト実行関数
func safeRequest(client *fasthttp.Client, req *fasthttp.Request, resp *fasthttp.Response) error {
	err := client.Do(req, resp)
	if err != nil {
		return fmt.Errorf("リクエスト実行エラー: %w", err)
	}
	
	// ステータスコードチェック
	statusCode := resp.StatusCode()
	if statusCode >= 400 {
		return &HTTPError{
			StatusCode: statusCode,
			Message:    string(resp.Body()),
			URL:        string(req.RequestURI()),
		}
	}
	
	return nil
}

// リトライ付きリクエスト実行
func requestWithRetry(client *fasthttp.Client, req *fasthttp.Request, maxRetries int, backoffFactor time.Duration) (*fasthttp.Response, error) {
	resp := fasthttp.AcquireResponse()
	
	for attempt := 0; attempt <= maxRetries; attempt++ {
		resp.Reset()
		
		err := safeRequest(client, req, resp)
		if err == nil {
			return resp, nil
		}
		
		// リトライ可能なエラーかチェック
		if httpErr, ok := err.(*HTTPError); ok {
			// 4xxエラーはリトライしない
			if httpErr.StatusCode >= 400 && httpErr.StatusCode < 500 {
				fasthttp.ReleaseResponse(resp)
				return nil, err
			}
		}
		
		if attempt == maxRetries {
			fasthttp.ReleaseResponse(resp)
			return nil, fmt.Errorf("最大試行回数に達しました: %w", err)
		}
		
		// バックオフ待機
		waitTime := backoffFactor * time.Duration(1<<attempt)
		log.Printf("試行 %d 失敗, %v 後に再試行: %v", attempt+1, waitTime, err)
		time.Sleep(waitTime)
	}
	
	fasthttp.ReleaseResponse(resp)
	return nil, fmt.Errorf("予期しないエラー")
}

// レート制限対応クライアント
type RateLimitedClient struct {
	client     *fasthttp.Client
	limiter    chan struct{}
	retryDelay time.Duration
}

func NewRateLimitedClient(requestsPerSecond int, retryDelay time.Duration) *RateLimitedClient {
	return &RateLimitedClient{
		client: &fasthttp.Client{
			ReadTimeout:  time.Second * 30,
			WriteTimeout: time.Second * 30,
		},
		limiter:    make(chan struct{}, requestsPerSecond),
		retryDelay: retryDelay,
	}
}

func (rlc *RateLimitedClient) Do(req *fasthttp.Request, resp *fasthttp.Response) error {
	// レート制限
	select {
	case rlc.limiter <- struct{}{}:
		defer func() { <-rlc.limiter }()
	default:
		time.Sleep(rlc.retryDelay)
		return rlc.Do(req, resp)
	}
	
	return rlc.client.Do(req, resp)
}

func main() {
	client := &fasthttp.Client{
		ReadTimeout:               time.Second * 30,
		WriteTimeout:              time.Second * 30,
		MaxIdemponentCallAttempts: 1, // fasthttpの自動リトライを無効化
	}
	
	req := fasthttp.AcquireRequest()
	defer fasthttp.ReleaseRequest(req)
	
	// 正常なリクエストテスト
	req.SetRequestURI("https://httpbin.org/get")
	req.Header.SetMethod(fasthttp.MethodGet)
	
	resp, err := requestWithRetry(client, req, 3, time.Second)
	if err != nil {
		log.Printf("リクエスト失敗: %v", err)
	} else {
		fmt.Printf("成功: ステータス %d\n", resp.StatusCode())
		fasthttp.ReleaseResponse(resp)
	}
	
	// エラーレスポンステスト
	req.Reset()
	req.SetRequestURI("https://httpbin.org/status/404")
	req.Header.SetMethod(fasthttp.MethodGet)
	
	resp, err = requestWithRetry(client, req, 3, time.Second)
	if err != nil {
		if httpErr, ok := err.(*HTTPError); ok {
			fmt.Printf("HTTPエラー: %d - %s\n", httpErr.StatusCode, httpErr.Message)
		} else {
			log.Printf("その他のエラー: %v", err)
		}
	}
	if resp != nil {
		fasthttp.ReleaseResponse(resp)
	}
	
	// タイムアウトテスト
	timeoutClient := &fasthttp.Client{
		ReadTimeout:  time.Millisecond * 100, // 短いタイムアウト
		WriteTimeout: time.Millisecond * 100,
	}
	
	req.Reset()
	req.SetRequestURI("https://httpbin.org/delay/1")
	req.Header.SetMethod(fasthttp.MethodGet)
	
	resp, err = requestWithRetry(timeoutClient, req, 2, time.Millisecond*500)
	if err != nil {
		log.Printf("タイムアウトエラー(期待される): %v", err)
	}
	if resp != nil {
		fasthttp.ReleaseResponse(resp)
	}
	
	// レート制限付きクライアントのテスト
	rateLimitedClient := NewRateLimitedClient(5, time.Millisecond*200)
	
	for i := 0; i < 10; i++ {
		req.Reset()
		resp := fasthttp.AcquireResponse()
		
		req.SetRequestURI(fmt.Sprintf("https://httpbin.org/get?request=%d", i))
		req.Header.SetMethod(fasthttp.MethodGet)
		
		start := time.Now()
		err := rateLimitedClient.Do(req, resp)
		duration := time.Since(start)
		
		if err != nil {
			log.Printf("リクエスト %d エラー: %v", i, err)
		} else {
			fmt.Printf("リクエスト %d 完了: ステータス %d, 所要時間: %v\n", 
				i, resp.StatusCode(), duration)
		}
		
		fasthttp.ReleaseResponse(resp)
	}
	
	// 並行エラーハンドリング例
	const numRequests = 5
	results := make(chan string, numRequests)
	
	for i := 0; i < numRequests; i++ {
		go func(id int) {
			req := fasthttp.AcquireRequest()
			defer fasthttp.ReleaseRequest(req)
			
			// 50%の確率で404エラーを発生させる
			url := "https://httpbin.org/get"
			if id%2 == 0 {
				url = "https://httpbin.org/status/404"
			}
			
			req.SetRequestURI(url)
			req.Header.SetMethod(fasthttp.MethodGet)
			
			resp, err := requestWithRetry(client, req, 2, time.Millisecond*500)
			if err != nil {
				results <- fmt.Sprintf("ゴルーチン %d: エラー - %v", id, err)
			} else {
				results <- fmt.Sprintf("ゴルーチン %d: 成功 - ステータス %d", id, resp.StatusCode())
				fasthttp.ReleaseResponse(resp)
			}
		}(i)
	}
	
	// 結果収集
	for i := 0; i < numRequests; i++ {
		result := <-results
		fmt.Println(result)
	}
}

パフォーマンス最適化とベンチマーク

package main

import (
	"fmt"
	"log"
	"runtime"
	"sync"
	"time"
	"github.com/valyala/fasthttp"
)

// パフォーマンス監視用の構造体
type PerformanceMonitor struct {
	requestCount    int64
	errorCount      int64
	totalDuration   time.Duration
	mu              sync.RWMutex
	startTime       time.Time
}

func NewPerformanceMonitor() *PerformanceMonitor {
	return &PerformanceMonitor{
		startTime: time.Now(),
	}
}

func (pm *PerformanceMonitor) RecordRequest(duration time.Duration, hasError bool) {
	pm.mu.Lock()
	defer pm.mu.Unlock()
	
	pm.requestCount++
	pm.totalDuration += duration
	if hasError {
		pm.errorCount++
	}
}

func (pm *PerformanceMonitor) GetStats() (int64, int64, time.Duration, float64) {
	pm.mu.RLock()
	defer pm.mu.RUnlock()
	
	elapsed := time.Since(pm.startTime)
	rps := float64(pm.requestCount) / elapsed.Seconds()
	
	return pm.requestCount, pm.errorCount, pm.totalDuration, rps
}

// 最適化されたクライアント設定
func createOptimizedClient() *fasthttp.Client {
	return &fasthttp.Client{
		// 効率的なタイムアウト設定
		ReadTimeout:  time.Second * 10,
		WriteTimeout: time.Second * 10,
		
		// コネクション最適化
		MaxConnsPerHost:       100,
		MaxIdleConnDuration:   time.Minute * 5,
		MaxConnDuration:       time.Hour,
		MaxIdemponentCallAttempts: 3,
		
		// TCPパフォーマンス最適化
		ReadBufferSize:  64 * 1024,  // 64KB
		WriteBufferSize: 64 * 1024,  // 64KB
		
		// Keep-Alive設定
		MaxConnWaitTimeout: time.Second * 5,
	}
}

// バッチリクエスト処理
func batchRequests(client *fasthttp.Client, urls []string, concurrency int) {
	monitor := NewPerformanceMonitor()
	semaphore := make(chan struct{}, concurrency)
	var wg sync.WaitGroup
	
	fmt.Printf("バッチ処理開始: %d URL, 並行数: %d\n", len(urls), concurrency)
	
	for i, url := range urls {
		wg.Add(1)
		go func(id int, targetURL string) {
			defer wg.Done()
			
			// セマフォで並行数制御
			semaphore <- struct{}{}
			defer func() { <-semaphore }()
			
			req := fasthttp.AcquireRequest()
			resp := fasthttp.AcquireResponse()
			defer fasthttp.ReleaseRequest(req)
			defer fasthttp.ReleaseResponse(resp)
			
			req.SetRequestURI(targetURL)
			req.Header.SetMethod(fasthttp.MethodGet)
			
			start := time.Now()
			err := client.Do(req, resp)
			duration := time.Since(start)
			
			hasError := err != nil || resp.StatusCode() >= 400
			monitor.RecordRequest(duration, hasError)
			
			if id%100 == 0 {
				fmt.Printf("進捗: %d/%d 完了\n", id, len(urls))
			}
		}(i, url)
	}
	
	wg.Wait()
	
	// 統計表示
	requests, errors, totalDuration, rps := monitor.GetStats()
	avgDuration := totalDuration / time.Duration(requests)
	
	fmt.Printf("\n=== バッチ処理結果 ===\n")
	fmt.Printf("総リクエスト数: %d\n", requests)
	fmt.Printf("エラー数: %d (%.2f%%)\n", errors, float64(errors)/float64(requests)*100)
	fmt.Printf("平均レスポンス時間: %v\n", avgDuration)
	fmt.Printf("RPS (Requests Per Second): %.2f\n", rps)
}

// コネクションプール監視
func monitorConnectionPool(client *fasthttp.Client) {
	ticker := time.NewTicker(time.Second * 5)
	defer ticker.Stop()
	
	for {
		select {
		case <-ticker.C:
			// ここでは簡易的なメモリ使用量を表示
			var m runtime.MemStats
			runtime.ReadMemStats(&m)
			
			fmt.Printf("メモリ使用量: Alloc = %.2f MB, Sys = %.2f MB, NumGC = %d\n",
				float64(m.Alloc)/1024/1024,
				float64(m.Sys)/1024/1024,
				m.NumGC)
		}
	}
}

// 負荷テスト関数
func loadTest(targetURL string, duration time.Duration, concurrency int) {
	client := createOptimizedClient()
	monitor := NewPerformanceMonitor()
	
	fmt.Printf("負荷テスト開始: %s, 時間: %v, 並行数: %d\n", targetURL, duration, concurrency)
	
	// メモリ監視を別ゴルーチンで開始
	go monitorConnectionPool(client)
	
	semaphore := make(chan struct{}, concurrency)
	endTime := time.Now().Add(duration)
	var wg sync.WaitGroup
	
	for time.Now().Before(endTime) {
		wg.Add(1)
		go func() {
			defer wg.Done()
			
			semaphore <- struct{}{}
			defer func() { <-semaphore }()
			
			req := fasthttp.AcquireRequest()
			resp := fasthttp.AcquireResponse()
			defer fasthttp.ReleaseRequest(req)
			defer fasthttp.ReleaseResponse(resp)
			
			req.SetRequestURI(targetURL)
			req.Header.SetMethod(fasthttp.MethodGet)
			
			start := time.Now()
			err := client.Do(req, resp)
			requestDuration := time.Since(start)
			
			hasError := err != nil || resp.StatusCode() >= 400
			monitor.RecordRequest(requestDuration, hasError)
		}()
	}
	
	wg.Wait()
	
	// 最終統計
	requests, errors, totalDuration, rps := monitor.GetStats()
	avgDuration := totalDuration / time.Duration(requests)
	
	fmt.Printf("\n=== 負荷テスト結果 ===\n")
	fmt.Printf("総リクエスト数: %d\n", requests)
	fmt.Printf("エラー数: %d (%.2f%%)\n", errors, float64(errors)/float64(requests)*100)
	fmt.Printf("平均レスポンス時間: %v\n", avgDuration)
	fmt.Printf("最大RPS: %.2f\n", rps)
	fmt.Printf("スループット: %.2f MB/s (推定)\n", rps*1024/1024) // 1KB/requestと仮定
}

func main() {
	// 基本的なパフォーマンステスト
	urls := make([]string, 1000)
	for i := range urls {
		urls[i] = fmt.Sprintf("https://httpbin.org/get?id=%d", i)
	}
	
	client := createOptimizedClient()
	
	// バッチリクエストテスト
	batchRequests(client, urls[:100], 20)
	
	// 負荷テスト(実際の本番環境では適切なテストサーバーを使用)
	// loadTest("https://httpbin.org/get", time.Minute, 50)
	
	// ベンチマーク比較(fasthttp vs net/http)
	fmt.Println("\n=== fasthttpベンチマーク例 ===")
	fmt.Println("実際のベンチマーク結果:")
	fmt.Println("fasthttp: 865 ns/op, 0 allocs/op")
	fmt.Println("net/http: 12567 ns/op, 35 allocs/op")
	fmt.Println("性能向上: ~14.5倍高速, ゼロアロケーション")
	
	// メモリ効率性デモ
	demonstrateMemoryEfficiency()
}

func demonstrateMemoryEfficiency() {
	fmt.Println("\n=== メモリ効率性デモ ===")
	
	// オブジェクトプールの活用
	req := fasthttp.AcquireRequest()
	resp := fasthttp.AcquireResponse()
	
	// 使用後は必ずプールに戻す
	defer fasthttp.ReleaseRequest(req)
	defer fasthttp.ReleaseResponse(resp)
	
	// ゼロアロケーションの文字列操作例
	uri := make([]byte, 0, 100)
	uri = append(uri, "https://example.com/api"...)
	uri = append(uri, "?param=value"...)
	
	req.SetRequestURIBytes(uri)
	
	fmt.Println("オブジェクトプールとゼロアロケーション操作を実装")
	fmt.Printf("URI設定完了: %s\n", req.RequestURI())
}