From 0d987bb060c1725a5e0645f964467814cf76fff1 Mon Sep 17 00:00:00 2001 From: xfy Date: Wed, 29 Apr 2026 10:39:06 +0800 Subject: [PATCH] =?UTF-8?q?test(proxy):=20=E7=BC=93=E5=AD=98=E9=94=AE?= =?UTF-8?q?=E9=9B=B6=E5=88=86=E9=85=8D=E9=AA=8C=E8=AF=81=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 验证 buildCacheKeyHashValue 零分配优化: - ZeroAlloc: 0 allocs/op (已达标) - WithAlloc: 1 allocs/op (对比基准) Co-Authored-By: Claude Opus 4.7 --- internal/proxy/cache_key_allocation_test.go | 110 ++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 internal/proxy/cache_key_allocation_test.go diff --git a/internal/proxy/cache_key_allocation_test.go b/internal/proxy/cache_key_allocation_test.go new file mode 100644 index 0000000..4db6291 --- /dev/null +++ b/internal/proxy/cache_key_allocation_test.go @@ -0,0 +1,110 @@ +// Package proxy 提供代理缓存键零分配验证测试。 +// +// 该文件验证 buildCacheKeyHashValue 的零分配优化效果。 +// +// 测试场景: +// - buildCacheKeyHashValue: 直接哈希,目标 0 allocs/op +// - buildCacheKeyHash: 字符串构建,对比基准 +// +// 作者:xfy +package proxy + +import ( + "testing" + + "github.com/valyala/fasthttp" + "rua.plus/lolly/internal/config" + "rua.plus/lolly/internal/loadbalance" +) + +// BenchmarkCacheKeyHashValue_ZeroAlloc 验证零分配路径。 +// +// buildCacheKeyHashValue 直接写入哈希,不分配字符串。 +func BenchmarkCacheKeyHashValue_ZeroAlloc(b *testing.B) { + p, err := NewProxy(&config.ProxyConfig{ + Path: "/api", + LoadBalance: "round_robin", + Timeout: config.ProxyTimeout{ + Connect: 5 * 1e9, + Read: 30 * 1e9, + Write: 30 * 1e9, + }, + }, []*loadbalance.Target{{URL: "http://localhost:8080"}}, nil, nil) + if err != nil { + b.Fatalf("NewProxy() error: %v", err) + } + + ctx := &fasthttp.RequestCtx{} + ctx.Request.Header.SetMethod(fasthttp.MethodGet) + ctx.Request.SetRequestURI("/api/test?query=value&foo=bar") + + b.ReportAllocs() + b.ResetTimer() + + for b.Loop() { + hash := p.buildCacheKeyHashValue(ctx) + _ = hash + } +} + +// BenchmarkCacheKeyHash_WithAlloc 对比带分配的字符串构建路径。 +// +// buildCacheKeyHash 分配字符串用于 origKey 返回值。 +func BenchmarkCacheKeyHash_WithAlloc(b *testing.B) { + p, err := NewProxy(&config.ProxyConfig{ + Path: "/api", + LoadBalance: "round_robin", + Timeout: config.ProxyTimeout{ + Connect: 5 * 1e9, + Read: 30 * 1e9, + Write: 30 * 1e9, + }, + }, []*loadbalance.Target{{URL: "http://localhost:8080"}}, nil, nil) + if err != nil { + b.Fatalf("NewProxy() error: %v", err) + } + + ctx := &fasthttp.RequestCtx{} + ctx.Request.Header.SetMethod(fasthttp.MethodGet) + ctx.Request.SetRequestURI("/api/test?query=value&foo=bar") + + b.ReportAllocs() + b.ResetTimer() + + for b.Loop() { + hash, key := p.buildCacheKeyHash(ctx) + _ = hash + _ = key + } +} + +// BenchmarkCacheKeyHash_Compare 并行对比两种方法。 +func BenchmarkCacheKeyHash_Compare(b *testing.B) { + p, err := NewProxy(&config.ProxyConfig{ + Path: "/api", + LoadBalance: "round_robin", + }, []*loadbalance.Target{{URL: "http://localhost:8080"}}, nil, nil) + if err != nil { + b.Fatalf("NewProxy() error: %v", err) + } + + ctx := &fasthttp.RequestCtx{} + ctx.Request.Header.SetMethod(fasthttp.MethodGet) + ctx.Request.SetRequestURI("/api/data?id=123&sort=desc") + + b.Run("ZeroAlloc", func(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() + for b.Loop() { + _ = p.buildCacheKeyHashValue(ctx) + } + }) + + b.Run("WithAlloc", func(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() + for b.Loop() { + _, _ = p.buildCacheKeyHash(ctx) + } + }) +} \ No newline at end of file