Eliminating Go bounds checks with unsafe

https://news.ycombinator.com/rss Hits: 7
Summary

Eliminating Go bounds checks with unsafe Hot path optimization: unsafe pointer arithmetic to eliminate bound checks the Go compiler can't remove, given you can prove they are truly unnecessary. July 06, 2026 Part of the Optimization catalog series: When float division beats integer division How 4 bytes of padding make array clearing 49% faster Eliminating Go bound checks with unsafe (this post) Bound checks elimination (BCE) is probably one of the most robust, most productive optimization techniques in the Go world. This is my go-to technique, I think, when I'm starting to optimize any Go hot path. Why is it so robust? Because it reduces number of instructions and number of branches in a hot path. This alone is excellent because it reduces number of wasted cycles, but there are additional benefits on top of that. If your code already experiences cache capacity and/or conflict misses lowering number of instructions can help with those significantly. We are talking about L1 icache, the uop cache and, maybe, frontend branch prediction caches. Also register pressure, BCE can help with that too. While being so robust, bound checks are easy to detect and sometimes relatively easy to eliminate. Long story short, BCE is usually a quick win worth trying first. However sometimes it's not easy to eliminate bound checks with conventional methods and that's where the unsafe techniques enter and this is what this post is about. First, what are the Bound Checks? Go is a safe language and provides some guarantees, e.g. the guarantee that you can't access out-of-range slice elements. To do that the compiler adds a bunch of assembly code that makes sure the runtime panics when the out-of-range index is accessed. Let me quickly illustrate it by this tiny example: func load(src []byte, i int) byte { return src[i] } If I compile it with the -B flag which disables bound checks it produces this concise assembly: 0x71d MOVQ AX, 0x8(SP) 0x722 MOVZX 0(AX)(DI*1), AX 0x726 RET Assembly with th...

First seen: 2026-07-20 09:02

Last seen: 2026-07-20 15:11