From 51c3d7409503dca472f7848f968c83654317689a Mon Sep 17 00:00:00 2001 From: Maisem Ali Date: Tue, 26 Jul 2022 21:15:22 -0700 Subject: [PATCH] types/views: add BenchmarkSliceIteration ``` goos: darwin goarch: arm64 pkg: tailscale.com/types/views BenchmarkSliceIteration/Len-10 340093 3212 ns/op 0 B/op 0 allocs/op BenchmarkSliceIteration/Cached-Len-10 366727 3211 ns/op 0 B/op 0 allocs/op BenchmarkSliceIteration/direct-10 361561 3290 ns/op 0 B/op 0 allocs/op PASS ok tailscale.com/types/views 3.662s ``` Signed-off-by: Maisem Ali --- types/views/views_test.go | 56 +++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/types/views/views_test.go b/types/views/views_test.go index b22f253b3..75fdc0f59 100644 --- a/types/views/views_test.go +++ b/types/views/views_test.go @@ -15,6 +15,51 @@ import ( qt "github.com/frankban/quicktest" ) +type viewStruct struct { + Int int + Addrs IPPrefixSlice + Strings Slice[string] + AddrsPtr *IPPrefixSlice `json:",omitempty"` + StringsPtr *Slice[string] `json:",omitempty"` +} + +func BenchmarkSliceIteration(b *testing.B) { + var data []viewStruct + for i := 0; i < 10000; i++ { + data = append(data, viewStruct{Int: i}) + } + b.ResetTimer() + b.Run("Len", func(b *testing.B) { + b.ReportAllocs() + dv := SliceOf(data) + for it := 0; it < b.N; it++ { + sum := 0 + for i := 0; i < dv.Len(); i++ { + sum += dv.At(i).Int + } + } + }) + b.Run("Cached-Len", func(b *testing.B) { + b.ReportAllocs() + dv := SliceOf(data) + for it := 0; it < b.N; it++ { + sum := 0 + for i, n := 0, dv.Len(); i < n; i++ { + sum += dv.At(i).Int + } + } + }) + b.Run("direct", func(b *testing.B) { + b.ReportAllocs() + for it := 0; it < b.N; it++ { + sum := 0 + for _, d := range data { + sum += d.Int + } + } + }) +} + func TestViewsJSON(t *testing.T) { mustCIDR := func(cidrs ...string) (out []netip.Prefix) { for _, cidr := range cidrs { @@ -22,12 +67,6 @@ func TestViewsJSON(t *testing.T) { } return } - type viewStruct struct { - Addrs IPPrefixSlice - Strings Slice[string] - AddrsPtr *IPPrefixSlice `json:",omitempty"` - StringsPtr *Slice[string] `json:",omitempty"` - } ipp := IPPrefixSliceOf(mustCIDR("192.168.0.0/24")) ss := SliceOf([]string{"bar"}) tests := []struct { @@ -38,17 +77,18 @@ func TestViewsJSON(t *testing.T) { { name: "empty", in: viewStruct{}, - wantJSON: `{"Addrs":null,"Strings":null}`, + wantJSON: `{"Int":0,"Addrs":null,"Strings":null}`, }, { name: "everything", in: viewStruct{ + Int: 1234, Addrs: ipp, AddrsPtr: &ipp, StringsPtr: &ss, Strings: ss, }, - wantJSON: `{"Addrs":["192.168.0.0/24"],"Strings":["bar"],"AddrsPtr":["192.168.0.0/24"],"StringsPtr":["bar"]}`, + wantJSON: `{"Int":1234,"Addrs":["192.168.0.0/24"],"Strings":["bar"],"AddrsPtr":["192.168.0.0/24"],"StringsPtr":["bar"]}`, }, }