From c8a4ce9a88fbe3122d796641406016ae4e83213d Mon Sep 17 00:00:00 2001 From: kim Date: Wed, 9 Jul 2025 01:38:33 +0200 Subject: [performance] use our own typed value context types for Value() key checking to improve performance (#4316) Replaces our gtscontext package context.Context handling with our own typed contexts instead of `context.WithValue()`. I wrote a quick benchmark consisting of (printlns to stop the compiler optimizing instructions away): ```golang func BenchmarkContexts(b *testing.B) { var receiving *gtsmodel.Account var requesting *gtsmodel.Account var otherIRIs []*url.URL b.RunParallel(func(pb *testing.PB) { for pb.Next() { ctx := context.Background() ctx = gtscontext.SetBarebones(ctx) ctx = gtscontext.SetFastFail(ctx) ctx = gtscontext.SetDryRun(ctx) ctx = gtscontext.SetReceivingAccount(ctx, receiving) ctx = gtscontext.SetRequestingAccount(ctx, requesting) ctx = gtscontext.SetOtherIRIs(ctx, otherIRIs) if !gtscontext.Barebones(ctx) { println("oh no!") } if !gtscontext.IsFastfail(ctx) { println("oh no!") } if !gtscontext.DryRun(ctx) { println("oh no!") } if gtscontext.ReceivingAccount(ctx) != nil { println("oh no!") } if gtscontext.RequestingAccount(ctx) != nil { println("oh no!") } if len(gtscontext.OtherIRIs(ctx)) > 0 { println("oh no!") } } }) } ``` Before results: ```shell kim @ ~/Projects/main/gts.4 --> go test -v -run=none -bench=.* -benchmem ./internal/gtscontext/ -count=5 goos: linux goarch: amd64 pkg: code.superseriousbusiness.org/gotosocial/internal/gtscontext cpu: AMD Ryzen 7 7840U w/ Radeon 780M Graphics BenchmarkContexts BenchmarkContexts-16 19050348 61.73 ns/op 288 B/op 6 allocs/op BenchmarkContexts-16 18245772 61.71 ns/op 288 B/op 6 allocs/op BenchmarkContexts-16 18853680 61.80 ns/op 288 B/op 6 allocs/op BenchmarkContexts-16 18561621 62.67 ns/op 288 B/op 6 allocs/op BenchmarkContexts-16 17819241 62.89 ns/op 288 B/op 6 allocs/op PASS ok code.superseriousbusiness.org/gotosocial/internal/gtscontext 6.112s ``` After results: ```shell kim @ ~/Projects/main/gts.4 --> go test -v -run=none -bench=.* -benchmem ./internal/gtscontext/ -count=5 goos: linux goarch: amd64 pkg: code.superseriousbusiness.org/gotosocial/internal/gtscontext cpu: AMD Ryzen 7 7840U w/ Radeon 780M Graphics BenchmarkContexts BenchmarkContexts-16 28038618 41.67 ns/op 144 B/op 6 allocs/op BenchmarkContexts-16 26537552 42.50 ns/op 144 B/op 6 allocs/op BenchmarkContexts-16 26720542 42.39 ns/op 144 B/op 6 allocs/op BenchmarkContexts-16 27408031 43.15 ns/op 144 B/op 6 allocs/op BenchmarkContexts-16 25597026 44.02 ns/op 144 B/op 6 allocs/op PASS ok code.superseriousbusiness.org/gotosocial/internal/gtscontext 5.997s ``` Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4316 Co-authored-by: kim Co-committed-by: kim --- internal/gtscontext/context_test.go | 53 +++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 internal/gtscontext/context_test.go (limited to 'internal/gtscontext/context_test.go') diff --git a/internal/gtscontext/context_test.go b/internal/gtscontext/context_test.go new file mode 100644 index 000000000..cf61acb4a --- /dev/null +++ b/internal/gtscontext/context_test.go @@ -0,0 +1,53 @@ +package gtscontext_test + +import ( + "context" + "net/url" + "testing" + + "code.superseriousbusiness.org/gotosocial/internal/gtscontext" + "code.superseriousbusiness.org/gotosocial/internal/gtsmodel" +) + +func BenchmarkContexts(b *testing.B) { + var receiving *gtsmodel.Account + var requesting *gtsmodel.Account + var otherIRIs []*url.URL + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + ctx := context.Background() + + ctx = gtscontext.SetBarebones(ctx) + ctx = gtscontext.SetFastFail(ctx) + ctx = gtscontext.SetDryRun(ctx) + ctx = gtscontext.SetReceivingAccount(ctx, receiving) + ctx = gtscontext.SetRequestingAccount(ctx, requesting) + ctx = gtscontext.SetOtherIRIs(ctx, otherIRIs) + + if !gtscontext.Barebones(ctx) { + println("oh no!") + } + + if !gtscontext.IsFastfail(ctx) { + println("oh no!") + } + + if !gtscontext.DryRun(ctx) { + println("oh no!") + } + + if gtscontext.ReceivingAccount(ctx) != nil { + println("oh no!") + } + + if gtscontext.RequestingAccount(ctx) != nil { + println("oh no!") + } + + if len(gtscontext.OtherIRIs(ctx)) > 0 { + println("oh no!") + } + } + }) +} -- cgit v1.2.3