Unused methods influences benchmark

agolangf · · 466 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<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&#39;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&#39;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&#39;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&#39;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&#39;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&#39;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&#39;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&#39;s 1.98ns WITH the method and 2.38ns with it removed. </p> <p>I&#39;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&#39;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&#39;t require extra package variables just for it; e.g. if the <code>next</code> array/slice is only used for this then I&#39;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&#39;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&#39;t know and can&#39;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

466 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传