Skip to content

Instantly share code, notes, and snippets.

@florianl
Created November 4, 2025 13:43
Show Gist options
  • Select an option

  • Save florianl/6ca76ed6906bf9ecd12465db10b50fb6 to your computer and use it in GitHub Desktop.

Select an option

Save florianl/6ca76ed6906bf9ecd12465db10b50fb6 to your computer and use it in GitHub Desktop.
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