<p>Hi,
following code: <a href="https://play.golang.org/p/2obBQPsDyD" rel="nofollow">https://play.golang.org/p/2obBQPsDyD</a></p>
<p>If I remove the dummy function (simply delete it) the benchmark gets faster. With the dummy method it taks 1.52nd/op and with it removed 1.26ns/op. Because dummy is never used the compiler should just throw it out the window, shouldn't it?</p>
<p>Can anyone give a (somewhat in-depth) explanation why this is happening?</p>
<p>Greetings</p>
<hr/>**评论:**<br/><br/>barsonme: <pre><p>Interestingly enough I get the same results as OP no matter how many times I run it.</p>
<p>Removing optimizations equals them out at ~7.15 ns each. On my laptop, the dummy function ended up being an extra 71 bytes of instructions itself, but the built binary was 576 bytes larger. What CPU/os/arch combination do you have?</p>
<p>My guess: alignment or cache or something. Who knows?</p>
<p>Adding another dummy function equals out the results. Computers are magic.</p>
<p>Adding a third brings it back up. Adding a fourth back down. And so on...</p></pre>HectorJ: <pre><p>Have you re-run the benchmark several times?</p>
<p>There is always some small variance between runs, and with such a small difference I'm guessing it could be the reason.</p></pre>2obBQPsDyD: <pre><p>Yes. You can try it for yourself and <a href="/u/barsonme" rel="nofollow">/u/barsonme</a> was confirmed that he see's the same behavior.</p></pre>drvd: <pre><p>In depth explanation here: 0.25 ns is 1 clock cycle of a 4 GHz CPU. Just forget about it. If you cannot: Build a much much more sophisticated benchmark which can measure such slowdown reliable.</p></pre>2obBQPsDyD: <pre><p>It is not about the time it needs, it is about the fact that unused code has an influence on the speed of the code produced. I don't think the benchmark function of the Go standard library is unreliable.</p></pre>gohacker: <pre><p>Open an issue: <a href="https://github.com/golang/go/issues" rel="nofollow">https://github.com/golang/go/issues</a></p></pre>gohacker: <pre><p>The dummy func is NOT removed by the compiler, as one can easily see if they use objdump.</p></pre>aaaqqq: <pre><p>It'll be hard to find an explanation for a 0.26ns difference. For all we know, it could just be arbitrary. </p></pre>2obBQPsDyD: <pre><p>Why should it be arbitary?</p></pre>aaaqqq: <pre><p>To answer your question, I tried testing the code myself and I have to admit that this doesn't look arbitrary at all. </p>
<p>My results are along the same lines as yours. In my case, it was 2.38ns with the method in and 1.98ns with it removed. </p>
<p>Here's the weird part. If I add 2 print statements before the last print statement such that the end of the main function becomes something like: </p>
<pre><code>fmt.Println(result.T.Nanoseconds())
fmt.Println(result.N)
fmt.Println(result.String())
</code></pre>
<p>the times are reversed. Now it's 1.98ns WITH the method and 2.38ns with it removed. </p>
<p>I'm no expert on these matters but it looks like this might have something to do with garbage collection.</p></pre>dchapes: <pre><p>Running a benchmark on such a trivial function/method is almost the epitome of premature optimization; I can't image any situation where any sane version of such a method would every be a performance issue.</p>
<p>Write such a function/method in whatever way most clearly represents what it is doing (and doesn't require extra package variables just for it; e.g. if the <code>next</code> array/slice is only used for this then I'd re-write it just to avoid that).</p>
<p>An idiomatic Go way of writing this would be:</p>
<pre><code>func (o Orientation) Next() Orientation {
return (o + 1) % 4
}
</code></pre>
<p>Or possibly with another non-exported constant for the number of items being looped through: e.g. <a href="https://play.golang.org/p/h9IisYydgM" rel="nofollow">https://play.golang.org/p/h9IisYydgM</a></p></pre>2obBQPsDyD: <pre><p>It's not about the method or what it does. In fact I tried several different versions to see if there was a speed difference and this one turned out to be the fastest one.</p>
<p>The fact that removing unused code changes the performance of the from 1.52ns/op to 1.26ns/op was rather suprising to me (which in % is rather big). This could be completly harmless or a weird case for the compiler/optimizer or there could be a bigger problem somewhere.</p>
<p>I am wondering if something on such a small piece of code happens if similar things could happend on a bigger scale in a bigger piece of code? And because I don't know and can't judge that I posted here to see if someone knows.</p></pre>kavehmz: <pre><p><a href="/u/2obBQPsDyD" rel="nofollow">/u/2obBQPsDyD</a> can you post it in golang-nuts google group too? </p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传