Created
November 4, 2025 13:43
-
-
Save florianl/6ca76ed6906bf9ecd12465db10b50fb6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "math/rand" | |
| "slices" | |
| "sort" | |
| "testing" | |
| "time" | |
| ) | |
| type UnwindInfo struct { | |
| Opcode, FPOpcode, MergeOpcode uint8 | |
| Param, FPParam int32 | |
| } | |
| type StackDelta struct { | |
| Address uint64 | |
| Hints uint8 | |
| Info UnwindInfo | |
| } | |
| // generateDeltas creates a slice of StackDelta structs with random data. | |
| func generateDeltas(size int) []StackDelta { | |
| source := rand.NewSource(time.Now().UnixNano()) | |
| r := rand.New(source) | |
| deltas := make([]StackDelta, size) | |
| for i := 0; i < size; i++ { | |
| deltas[i] = StackDelta{ | |
| Address: uint64(r.Intn(size / 10)), | |
| Hints: uint8(r.Intn(256)), | |
| Info: UnwindInfo{ | |
| Opcode: uint8(r.Intn(10)), | |
| Param: int32(r.Intn(100)), | |
| }, | |
| } | |
| } | |
| return deltas | |
| } | |
| // compareStackDelta implements the comparison logic for slices.SortFunc. | |
| // It must return: | |
| // -1 if a should come before b (a < b) | |
| // 0 if a and b are considered equal | |
| // 1 if a should come after b (a > b) | |
| func compareStackDelta(a, b StackDelta) int { | |
| // 1. Primary Key: Address (uint64) | |
| if a.Address < b.Address { | |
| return -1 | |
| } | |
| if a.Address > b.Address { | |
| return 1 | |
| } | |
| if a.Info.Opcode != b.Info.Opcode { | |
| if a.Info.Opcode < b.Info.Opcode { | |
| return -1 | |
| } | |
| if a.Info.Opcode > b.Info.Opcode { | |
| return 1 | |
| } | |
| } | |
| if a.Info.Param < b.Info.Param { | |
| return -1 | |
| } | |
| if a.Info.Param > b.Info.Param { | |
| return 1 | |
| } | |
| return 0 | |
| } | |
| var benchSizes = []int{100, 1000, 10000, 100000} | |
| func BenchmarkSortSlice(b *testing.B) { | |
| for _, size := range benchSizes { | |
| b.Run("sort.Slice/N="+fmtSize(size), func(b *testing.B) { | |
| originalDeltas := generateDeltas(size) | |
| b.ReportAllocs() | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| deltas := make([]StackDelta, len(originalDeltas)) | |
| copy(deltas, originalDeltas) | |
| sort.Slice(deltas, func(i, j int) bool { | |
| if deltas[i].Address != deltas[j].Address { | |
| return deltas[i].Address < deltas[j].Address | |
| } | |
| if deltas[i].Info.Opcode != deltas[j].Info.Opcode { | |
| return deltas[i].Info.Opcode < deltas[j].Info.Opcode | |
| } | |
| return deltas[i].Info.Param < deltas[j].Info.Param | |
| }) | |
| } | |
| }) | |
| } | |
| } | |
| func BenchmarkSlicesSortFunc(b *testing.B) { | |
| for _, size := range benchSizes { | |
| b.Run("slices.SortFunc/N="+fmtSize(size), func(b *testing.B) { | |
| originalDeltas := generateDeltas(size) | |
| b.ReportAllocs() | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| deltas := make([]StackDelta, len(originalDeltas)) | |
| copy(deltas, originalDeltas) | |
| slices.SortFunc(deltas, compareStackDelta) | |
| } | |
| }) | |
| } | |
| } | |
| // helper to format the size number for the benchmark name | |
| func fmtSize(n int) string { | |
| if n >= 1000000 { | |
| return "1M" | |
| } | |
| if n >= 100000 { | |
| return "100K" | |
| } | |
| if n >= 10000 { | |
| return "10K" | |
| } | |
| if n >= 1000 { | |
| return "1K" | |
| } | |
| return "100" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment