How do you time a function in Go and return its runtime in milliseconds?
5 Answers
Go's defer
makes this trivial.
In Go 1.x, define the following functions:
func trace(s string) (string, time.Time) {
log.Println("START:", s)
return s, time.Now()
}
func un(s string, startTime time.Time) {
endTime := time.Now()
log.Println(" END:", s, "ElapsedTime in seconds:", endTime.Sub(startTime))
}
After that, you get Squeaky Clean one line elapsed time log messages:
func someFunction() {
defer un(trace("SOME_ARBITRARY_STRING_SO_YOU_CAN_KEEP_TRACK"))
//do a bunch of stuff here...
}
The clever magic is that the trace() is called at the beginning of the function, but the un() is deferred to the end. It's not atomic-clock accurate, due to the log statements, but if you need more accuracy, this kind of pattern is one of Go's marshmallowy good strengths.
EDIT:
This answer originally used legacy time package API. Reproduced here for historical value only:
For use w/ Go versions prior to 12-01-2011 weekly:
func trace(s string) (string, int64) {
log.Println("START:", s)
return s, time.Nanoseconds()
}
func un(s string, startTime int64) {
endTime := time.Nanoseconds()
log.Println(" END:", s, "ElapsedTime in seconds:", float32(endTime-startTime)/1E9)
}

- 10,045
- 1
- 36
- 33
-
1Hat Tip to Noah Heldman for suggesting an edit. Not sure why it was rejected, but will edit shortly. – amattn Jun 07 '13 at 20:50
Use the Go testing
package to benchmark the function. For example,
package main
import (
"fmt"
"testing"
)
// the function to be benchmarked
func Function(n int) int64 {
n64 := int64(n)
return n64 * n64
}
func BenchmarkFunction(b *testing.B) {
n := 42
for i := 0; i < b.N; i++ {
_ = Function(n)
}
}
func main() {
br := testing.Benchmark(BenchmarkFunction)
fmt.Println(br)
}
Output:
500000000 4.22 ns/op
You can also use the Go gotest command to run benchmarks.

- 158,998
- 31
- 281
- 276
-
This does not "return its runtime in milliseconds" as asked for in the question. – Johan Walles Apr 22 '21 at 04:40
Another easy way can be:
import (
"fmt"
"time"
)
start := time.Now()
// some computation
elapsed := time.Since(start)
fmt.Println(elapsed)
which will output something like 359.684612ms

- 214,103
- 147
- 703
- 753
Perhaps you can also use a Duration (elapsed) for this...looks a little bit nicer.
func trace(s string) (string, time.Time) {
log.Printf("trace start: %s\n", s)
return s, time.Now()
}
func un(s string, startTime time.Time) {
elapsed := time.Since(startTime)
log.Printf("trace end: %s, elapsed %f secs\n", s, elapsed.Seconds())
}

- 307
- 3
- 3
There are several options for timestamping and timers in the time package. See the documentation here: http://golang.org/pkg/time/

- 11,800
- 1
- 26
- 34
-
I've seen that documentation, but there are no examples with it used. Would I just go `timer := timer.Time() then timer.Stop()`? That doesn't seem to work. And how do I access the time in milliseconds? – The Puma Dec 02 '11 at 02:04