2

Measuring time around a function is easy in Go. But what if you need to measure it 5000 times per second in parallel?

I'm referring to Correctly measure time duration in Go which contains great answers about how to measure time in Go.

What is the cost of using time.Now() 5000 times per second or more? While it may depend on the underlying OS, let's consider on linux.

peterSO
  • 158,998
  • 31
  • 281
  • 276
Prune
  • 345
  • 4
  • 11
  • 3
    Then you redesign until measuring is again possible. If you do not have 5000 accurate clocks you cannot measure 5000 time spans concurrently. This is a physical truth, unrelated to Go. You have to find a different solution, e.g. sampling, averaging or other statistical tricks or sacrifying accuracy. – Volker Mar 26 '18 at 11:56

1 Answers1

1

Time measurement depends on the programming language and its implementation, the operating system and its implementation, the hardware architecture, implementation, and speed, and so on.

You need to focus on facts, not speculation. In Go, start with some benchmarks. For example,

since_test.go:

package main

import (
    "testing"
    "time"
)

var now time.Time

func BenchmarkNow(b *testing.B) {
    for N := 0; N < b.N; N++ {
        now = time.Now()
    }
}

var since time.Duration
var start time.Time

func BenchmarkSince(b *testing.B) {
    for N := 0; N < b.N; N++ {
        start = time.Now()
        since = time.Since(start)
    }
}

Output:

$ go test since_test.go -bench=. -benchtime=1s
goos: linux
goarch: amd64
BenchmarkNow-4      30000000            47.5 ns/op
BenchmarkSince-4    20000000            98.1 ns/op
PASS
ok      command-line-arguments  3.536s
$ go version
go version devel +48c4eeeed7 Sun Mar 25 08:33:21 2018 +0000 linux/amd64
$ uname -srvio
Linux 4.13.0-37-generic #42-Ubuntu SMP Wed Mar 7 14:13:23 UTC 2018 x86_64 GNU/Linux
$ cat /proc/cpuinfo | grep 'model name' | uniq
model name  : Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz
$ 

Now, ask yourself if 5,000 times per second is necessary, practical, and reasonable.

What are your benchmark results?

peterSO
  • 158,998
  • 31
  • 281
  • 276
  • Thanks for this test script. `go test time_test.go -bench=. -benchtime=1s` `goos: linux` `goarch: amd64` `BenchmarkNow-8 20000000 82.0 ns/op` `BenchmarkSince-8 10000000 169 ns/op` `PASS` `ok command-line-arguments 3.628s` `go version` `go version go1.10 linux/amd64` This is running in a K8s cluster on GKE. – Prune Mar 27 '18 at 14:24
  • My real concern is, if I instrument my micro-services with Prometheus Histograms, which record `time.Duration`, to gather values for each requests, I will make a `time.Now()` then a `time.Duration().Seconds()` as many times per second as I have a request. I just wanted to evaluate the cost of each of these calls to ensure my metrology will not get the bottleneck of my microservices :) – Prune Mar 27 '18 at 14:25