time.Since() sometimes 497.5µs, sometimes 0s

agolangf · · 447 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Trying to check how long takes to get single row from PostgreSQL database and I use such a function to measure duration:</p> <pre><code>func PrintDuration(text string, start time.Time) { fmt.Printf(text+&#34;\n&#34;, time.Since(start)) } </code></pre> <p>Call it in such way at the start of function:</p> <pre><code>defer common.PrintDuration(&#34;GetRecord duration: %v&#34;, time.Now()) </code></pre> <p>Sometimes duration is +500µs, sometimes 0s. It seems that if duration is smaller than ~500µs, then duration somehow becomes 0.</p> <p>Basically I want to measure time difference at nanoseconds. What am I doing wrong?</p> <p>Windows 10 64bit, Go 1.8</p> <hr/>**评论:**<br/><br/>rsc: <pre><p>The Windows time source is based on clock tick counts updated by the Windows kernel. Either you observe a clock tick or not.</p></pre>sondeckis: <pre><p>Ok then. This is JAVA code:</p> <pre><code>long start = System.nanoTime(); ...do something System.out.println(&#34;Overall time: &#34; + (System.nanoTime() - start)); </code></pre> <p>How do I achieve this in Go? In linux, windows?</p></pre>amerine2: <pre><p>System.nanoTime is a &#34;precision timer&#34; in Java and not a wall-clock-like time.Time in Go. You&#39;re pretty much stuck with the windows time slice behavior. </p></pre>sondeckis: <pre><p>Well this is weird. I took it for granted that time will be from &#34;precision timer&#34;. So the same &#34;issue&#34; is in linux too? Minimal duration in linux will be 500µs too?</p></pre>LukeShu: <pre><p>The Linux kernel provides a nanosecond-precision clock; <code>CLOCK_REALTIME</code>, which is what <code>time.Now()</code> uses.</p></pre>kodablah: <pre><p>Note, for time diff measurement, it will be more accurate in the next release. See <a href="https://github.com/golang/go/issues/12914" rel="nofollow">https://github.com/golang/go/issues/12914</a>.</p></pre>Sythe2o0: <pre><pre><code>t := time.Now() ... fmt.Println(&#34;Overall time:&#34;, time.Since(t)) </code></pre> <p>If your question is &#34;how do I know if this function takes less than 500μs on average&#34;, then what you should do is write a benchmarking utility using Go&#39;s <a href="https://golang.org/pkg/testing/" rel="nofollow">testing</a> package. </p> <pre><code>func BenchmarkPostgresQuery(b *testing.B) { // Initialization b.ResetTimer() for n := 0; n &lt; b.N; n++ { // Query } } </code></pre></pre>sondeckis: <pre><ol> <li>Testing library calculates passed time in different way? or</li> <li>Function is just called multiple times and overall time has a maximum 500µs error?</li> </ol></pre>Sythe2o0: <pre><p>Benchmarking for time in Go runs the function as many times as it can within a given timespan. To quote the doc:</p> <blockquote> <p>The benchmark function must run the target code b.N times. During benchmark execution, b.N is adjusted until the benchmark function lasts long enough to be timed reliably. </p> </blockquote> <p>You can increase the amount of time spent if you want more accuracy, and there are other options you can use to tweak exactly how it works as described in the package. The error will only be in the total time spent, not in the time spent on a single call, so it will be negligible.</p></pre>rsc: <pre><p>The Go code you have is the way to measure the elapsed time. In Go 1.8 the resolution is based on a Windows API that counts clock ticks.</p> <p>In Go 1.9 we will probably start returning more accurate times for the code you posted, by using a different Windows time API, but that CL is still pending. </p></pre>Dummies102: <pre><p>you might have to wait for this monotonic clock RFC to be implemented <a href="https://github.com/golang/proposal/blob/master/design/12914-monotonic.md">https://github.com/golang/proposal/blob/master/design/12914-monotonic.md</a></p> <p>You might be able to compile go from source <a href="https://github.com/golang/go/commit/0e3355903d2ebcf5ee9e76096f51ac9a116a9dbb">https://github.com/golang/go/commit/0e3355903d2ebcf5ee9e76096f51ac9a116a9dbb</a></p></pre>sondeckis: <pre><p>After reading proposal I still don&#39;t get it why monotonic clock time is not by &#34;default&#34; and why using wall-clock-time is better than monotonic.</p></pre>Dummies102: <pre><p>I don&#39;t understand what you mean. If you read the proposal <a href="https://github.com/golang/proposal/blob/master/design/12914-monotonic.md#proposal">https://github.com/golang/proposal/blob/master/design/12914-monotonic.md#proposal</a> you&#39;ll see that they&#39;re going to make the monotonic clock the default clock for all operations involved in measuring time.</p></pre>earthboundkid: <pre><p>The problem is Windows. IIRC, it has a mode where it will count nanoseconds but it usually doesn&#39;t, and earlier versions of Go always kicked off the nanoseconds mode which was terrible for battery on laptops, so now it only switches modes sometimes. There maybe a syscall for it.</p> <p>Edit: See <a href="https://github.com/golang/go/issues/8687">https://github.com/golang/go/issues/8687</a> for some of the background </p></pre>sin2pifx: <pre><p>If the clock this is based on is reliable, then the average should give you the number you&#39;re looking for.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

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