Skip to content

Conversation

@pixelherodev
Copy link
Contributor

guid.Equal() is slow. We call it in a hot loop, and it shows up as a significant part of the profile for one component.

Added benchmarking, and tested a few different approaches. Was reminded by a coworker that == is valid for arrays in Go, and the compiler does a great job:

noam@sylphrena ~/pingthings/goapi/sttp/guid $ go test -bench .
goos: linux
goarch: amd64
pkg: github.com/sttp/goapi/sttp/guid
cpu: AMD Ryzen 9 7900X3D 12-Core Processor          
BenchmarkEqualityIndirect-24            	1000000000	        0.7779 ns/op
BenchmarkEqualityIndirectBaseline-24    	152718645	        7.887 ns/op
BenchmarkEqualityBaseline-24            	179326930	        6.897 ns/op
BenchmarkEqualityCurrent-24             	1000000000	        0.1949 ns/op
BenchmarkEqualityDirect-24              	1000000000	        0.1936 ns/op
PASS
ok  	github.com/sttp/goapi/sttp/guid	5.221s

The current approach has two problems:

  • First, the for loop approach is slow. It's hypothetically optimizable, but a == b works just fine for Guids and is ~35x faster.
  • Secondly, the indirection, while theoretically inlinable, is not being inlined. With the for loop, it adds 1ns/op - from 6.9 to 7.9 - but with the a == b approach, it adds 0.6ns - from 0.2 to 0.8ns.

Fixing both improves overall throughput from 8ns/op to 0.2ns/op, a ~40x improvement.

I fixed both APIs rather than remove one just so there's no breakage and it's easier to get reviewed.

@ritchiecarroll ritchiecarroll merged commit fee8d01 into sttp:main Mar 31, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants