Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test Go function execution time using standard lib

Tags:

go

I've written the following function that when used with Defer will surely do the trick but is there something in standard library I could use for this? I'm looking something similar to Python timeit which I could use directly from the shell?

package main

import (
    "fmt"
    "time"
)

func main() {
    defer timeTrack(time.Now(), "looptest")
    nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    var m []int
    for n := range nums {
        if n%2 == 0 {
            m = append(m, n)
        }
    }
}

func timeTrack(start time.Time, name string) {
    elapsed := time.Since(start)
    fmt.Printf("%s took %s", name, elapsed)
}
like image 449
Kimmo Hintikka Avatar asked Mar 11 '18 13:03

Kimmo Hintikka


People also ask

How do you find the execution time in go?

In Go, we have a package named time that is present in Go's standard library. This time package contains different useful functions that we can use to calculate the time taken by a code block or even a function in Go. The most widely used functions are time. Sleep(), time.

How do you test a go function?

To run any test function use “go test” command, which automates the execution of any function of the form TestXxx(*testing. T), where Xxx must not start with any lowercase letter.

How do you test concurrency in go?

If you want to test concurrency you'll need to make a few go routines and have them run, well, concurrently. You might try taking the locking out and intentionally get it to crash or misbehave by concurrently modifying things and then add the locking in to ensure it solves it.

Which command is used to run the tests in go?

Running subtests in Go The t. Run() command takes two arguments — the first matches against parameters passed to go test , and the second is the name of a test function.


2 Answers

Use the Go testing package. For example,

main.go:

package main

func doStuff() {
    nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    var m []int
    for n := range nums {
        if n%2 == 0 {
            m = append(m, n)
        }
    }
}

func main() {
    doStuff()
}

main_test.go:

package main

import "testing"

func BenchmarkStuff(b *testing.B) {
    for i := 0; i < b.N; i++ {
        doStuff()
    }
}

Output:

$ go test -bench=. -benchmem
goos: linux
goarch: amd64
pkg: main
BenchmarkStuff-4    5000000    276 ns/op    120 B/op    4 allocs/op

Using the information from the benchmark, you can improve performance. Reduce the number and size of allocations by using an estimate to initialize slice m.

func doStuff() {
    nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    m := make([]int, 0, len(nums)/2+1)
    for n := range nums {
        if n%2 == 0 {
            m = append(m, n)
        }
    }
}

Output:

$ go test -bench=. -benchmem
goos: linux
goarch: amd64
pkg: main
BenchmarkStuff-4    20000000    83.1 ns/op    48 B/op    1 allocs/op
like image 105
peterSO Avatar answered Nov 15 '22 07:11

peterSO


You can use testing

func BenchmarkFoo(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Foo()
    }
}
like image 43
A.Bau Avatar answered Nov 15 '22 08:11

A.Bau