DEV Community

Taras Tsugrii
Taras Tsugrii

Posted on


Trust performance advice... but verify.

Just like most things, performance advice also has an expiration date and it's important to keep this in mind when applying suggestions from blog posts or StackOverflow. That's why my favorite command line flag when building Go apps is --gcflags="-m=2". It enables printing optimizer decisions, making it possible to answer numerous interesting questions affecting performance, including whether function is inlined:

cannot inline main: function too complex: cost 523 exceeds budget 80
inlining call to largeReturner func() Large { return Large literal }
Enter fullscreen mode Exit fullscreen mode

or whether variable escapes to heap:

main.go:10:2: i escapes to heap:
main.go:10:2:  flow: ~r0 = &i:
main.go:10:2:    from &i (address-of) at main.go:11:9
main.go:10:2:    from return &i (return) at main.go:11:2
main.go:10:2: moved to heap: i
Enter fullscreen mode Exit fullscreen mode

Bonus: do you think l will escape to heap in the following code?

24 type Large struct {
25        data [1024]byte
26 }
28 func main() {
29        l := Large{}
30        fmt.Println(l)
Enter fullscreen mode Exit fullscreen mode

If you guessed yes, you are right :)

main.go:30:13: l escapes to heap:
main.go:30:13:  flow: ~arg0 = &{storage for l}:
main.go:30:13:    from l (spill) at main.go:30:13
main.go:30:13:    from ~arg0 = <N> (assign-pair) at main.go:30:13
main.go:30:13:  flow: {storage for []interface {} literal} = ~arg0:
main.go:30:13:    from []interface {} literal (slice-literal-element) at main.go:30:13
main.go:30:13:  flow: fmt.a = &{storage for []interface {} literal}:
main.go:30:13:    from []interface {} literal (spill) at ./main.go:30:13
main.go:30:13:    from fmt.a = []interface {} literal (assign) at main.go:30:13
main.go:30:13:  flow: {heap} = *fmt.a:
main.go:30:13:    from fmt.Fprintln(io.Writer(os.Stdout), fmt.a...) (call parameter) at main.go:30:13
main.go:30:13: l escapes to heap
Enter fullscreen mode Exit fullscreen mode

Why it matters? Even if the additional memory indirection is not a problem, heap allocations result in extra work for garbage collector and dreaded stop-the-world pauses.

Moral of the story? Know your tools and use them to verify all performance assumptions.

Top comments (0)

Timeless DEV post...

Git Concepts I Wish I Knew Years Ago

The most used technology by developers is not Javascript.

It's not Python or HTML.

It hardly even gets mentioned in interviews or listed as a pre-requisite for jobs.

I'm talking about Git and version control of course.

One does not simply learn git