3 ms·
I was wondering too. Does anybody know what makes defer so expensive?
by arendtio 8y ago
I was wondering too. Does anybody know what makes defer so expensive?
- jeffrallen 8y agoMemory allocation. Use defer to make code readable. Go code should be readable, so you can figure out if it is correct, and only then should it be fast. When benchmarking/profiling leads you to a hot spot in the code, rewrite it to remove defers.
- dis-sys 8y ago5300+ ns/op is for BenchMarkSize (1024) defer operations, so we are actually paying about 5ns/op for defer. Not sure why the author chose to report the ns/op number in its current way.
- eternalban 8y agoHe does not have a firm grasp on testing/B. The package is reporting timings for b.N loops ("ops"). There is no need for yet another loop. This is typical: https://github.com/cornelk/go-benchmark/blob/master/defer_test.go#L10 https://github.com/cornelk/go-benchmark/blob/master/defer_te...
- jerf 8y ago"so we are actually paying about 5ns/op for defer" Yeah, it's in the class of "things you should know about when optimizing tight loops", but not "things you should always be worrying about"; remember 5ns is on the order of a branch mispredict or an L2 cache miss [1]. If you haven't already squeezed out all the main memory accesses you can from your algorithm at 100ns a pop, or if you're in code dealing with networks (routinely micro seconds, even within datacenters; milli seconds if you have to leave), or files, or anything else like that, micro-optimizing defers is not going to have any visible results to your speed but can very badly damage your code's correctness and ease of writing and modifying. The other thing to know about defers is that they are not declarations, they are instructions; every time the program counter moves past one, another defer call is added to the stack of calls to make while exiting the function. So you do have to be careful about deferring in a loop, not so much because it's "dangerous" but just because it's easy to be unaware that the defers are not declarations. If you intend to do it, it's fine, it can just bite you if you do it accidentally. [1]: https://gist.github.com/jboner/2841832 https://gist.github.com/jboner/2841832
- joppy 8y agoDefer is for reclaiming resources, or other cleanup at the end of a function which cannot otherwise be handled by the language, and (usually?) this is not going to be in your hot path; for example opening and closing a file many many times is not really a good thing to do anyway.
- JulianMorrison 8y agoDefer also runs in the case of a panic. So it's not just a hidden goto.
- 32bitkid 8y agomore detail on why `defer` can/is more expensive (and not equivalent) to unrolling it: https://blog.golang.org/defer-panic-and-recover https://blog.golang.org/defer-panic-and-recover
- arendtio 8y agoThanks, that is what I was looking for. I used defer just as convenience and wasn't aware (anymore) that it does something different than just pushing the function call to the end. Maybe it's time to take the Golang tour again ;-)