Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce runtime of Go Encode() by another 25% #649

Merged
merged 5 commits into from
Jan 8, 2025

Conversation

willbeason
Copy link
Contributor

@willbeason willbeason commented Dec 10, 2024

This is (another) performance optimization change for the Go implementation of Encode(), which reduces the runtime by about 25%. This is the additional performance improvement I mentioned in #566.

There are two main changes here to accomplish this, either of which may be controversial as they do harm the code's readability. I have attempted to mitigate this with refactorings, and verified the extracted functions are inlined to avoid the additional overhead of function calls.

The first change is that all loops are unrolled. Given that all loops are unconditionally executed a constant number of times, this can be done without introducing any additional branches to the code.

The second change is that the precision rounding logic is modified to require zero divisions. This new method is significantly faster, but may change the final digits of codes requiring sub-centimeter precision (I don't believe this library has this as a supported use case?). There are no cases in the test suite in which this causes a difference, but if desired I can likely find such an edge case.

Before:

will@Janeway:~/GolandProjects/open-location-code/go$ go test --run=NONE --bench=Encode --benchtime=10s -cpuprofile=/home/will/cpu2.out
goos: linux
goarch: amd64
pkg: github.com/google/open-location-code/go
cpu: AMD Ryzen Threadripper 3970X 32-Core Processor 
BenchmarkEncode-64    	186547320	        64.70 ns/op	      16 B/op	       1 allocs/op
PASS
ok  	github.com/google/open-location-code/go	22.222s

After:

will@Janeway:~/GolandProjects/open-location-code/go$ git checkout -
Switched to branch 'optimize-2'
will@Janeway:~/GolandProjects/open-location-code/go$ go test --run=NONE --bench=Encode --benchtime=10s -cpuprofile=/home/will/cpu.out
goos: linux
goarch: amd64
pkg: github.com/google/open-location-code/go
cpu: AMD Ryzen Threadripper 3970X 32-Core Processor 
BenchmarkEncode-64    	233725107	        49.01 ns/op	      16 B/op	       1 allocs/op
PASS
ok  	github.com/google/open-location-code/go	21.471s

CPU profile of before:
profile002

CPU profile of after:
profile001

Unroll loops to improve performance.

Rewrite lat/lng rounding logic to avoid divides.

Signed-off-by: Will Beason <willbeason@gmail.com>
@willbeason willbeason marked this pull request as ready for review December 10, 2024 17:13
@drinckes drinckes self-assigned this Dec 23, 2024
go/encode.go Show resolved Hide resolved
go/encode.go Outdated Show resolved Hide resolved
go/encode.go Outdated Show resolved Hide resolved
go/encode.go Outdated Show resolved Hide resolved
Also merge logic for lat/lng iterations as they are identical.

Signed-off-by: Will Beason <willbeason@gmail.com>
@willbeason
Copy link
Contributor Author

Okay, improved comments and renamed functions as requested.

@willbeason willbeason requested a review from drinckes January 6, 2025 16:36
Copy link
Contributor

@drinckes drinckes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@drinckes drinckes merged commit 2586090 into google:main Jan 8, 2025
14 checks passed
@willbeason willbeason deleted the optimize-2 branch January 8, 2025 17:58
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