Skip to content

go: Eliminate memory allocations and reduce Decode time by 26%#749

Open
willbeason wants to merge 1 commit intogoogle:mainfrom
willbeason:main
Open

go: Eliminate memory allocations and reduce Decode time by 26%#749
willbeason wants to merge 1 commit intogoogle:mainfrom
willbeason:main

Conversation

@willbeason
Copy link
Contributor

@willbeason willbeason commented Mar 7, 2026

Use handwritten version of strings.Map logic. This avoids having to dynamically allocate and resize the byte slice, and allows the compiler to fully remove memory allocations from the operation. As a result, the time spent in StripCode is almost completely removed.

Before:

$ go test . -bench=Decode -benchtime=10s
...
goos: linux
goarch: amd64
pkg: github.com/google/open-location-code/go
cpu: AMD Ryzen Threadripper 3970X 32-Core Processor 
BenchmarkDecode-64    	32295574	       337.7 ns/op	      24 B/op	       1 allocs/op

After:

$ go test . -bench=Decode -benchtime=10s
...
goos: linux
goarch: amd64
pkg: github.com/google/open-location-code/go
cpu: AMD Ryzen Threadripper 3970X 32-Core Processor 
BenchmarkDecode-64    	48074581	       248.5 ns/op	       0 B/op	       0 allocs/op

CPU Profiles:

Before:

before

After:

after

@willbeason willbeason marked this pull request as ready for review March 7, 2026 05:05
@willbeason willbeason changed the title go: Eliminate memory allocations and improve speed of Decode by 26% go: Eliminate memory allocations and reduce Decode time by 26% Mar 7, 2026
@willbeason
Copy link
Contributor Author

After this PR, I have another that reduces Decode time further, to ~161.4ns/op. It's a separate optimization so I've split it out.

willbeason@12e4efd

Use handwritten version of strings.Map. This avoids having to dynamically
allocate and resize the byte slice, and allows the compiler to fully
remove memory allocations from the operation. As a result, the time
spent in StripCode is almost completely removed.
@willbeason
Copy link
Contributor Author

willbeason commented Mar 8, 2026

I see actually that StripCode() is part of the public API, so it's probably better that I don't change it and possibly break someone. I've removed that part of the change. It's still a significant speedup. Future performance improvements don't rely on it (yet), so I'm not worried about touching that now.

$ go test . -bench=Decode --benchtime=10s
goos: linux
goarch: amd64
pkg: github.com/google/open-location-code/go
cpu: AMD Ryzen Threadripper 3970X 32-Core Processor 
BenchmarkDecode-64    	38923173	       270.3 ns/op	      16 B/op	       1 allocs/op

@willbeason
Copy link
Contributor Author

On that note, I have a third optimization that gets us to ~75ns/op for Decode.

willbeason@54bdf28

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.

1 participant