5

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)
}
Kimmo Hintikka
  • 13,472
  • 7
  • 34
  • 63
  • 4
    Seems you are looking for [benchmarks](https://golang.org/pkg/testing/#hdr-Benchmarks). – Peter Mar 11 '18 at 13:31
  • See related / possible duplicate of [Order of the code and performance](https://stackoverflow.com/questions/41608578/order-of-the-code-and-performance/41608707#41608707). – icza Mar 11 '18 at 14:02

3 Answers3

6

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
peterSO
  • 158,998
  • 31
  • 281
  • 276
4

You can use testing

func BenchmarkFoo(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Foo()
    }
}
A.Bau
  • 82
  • 1
  • 10
0

You may use the "benchmark"-approach:

  1. Name the file %SOMETHING%_test.go

  2. Write tests, benchmarks, examples in it as follows:

    package main
    
    import (
        "testing"
    )
    
    func fn() {
        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 BenchmarkFunc(b *testing.B) {
        for i := 0; i < b.N; i++ {
            fn()
        }
    }
    
  3. Open the terminal and execute the following command:

    go test -bench .
    
  4. You will see the output like this:

    goos: darwin
    goarch: amd64
    BenchmarkFunc-2      5000000           360 ns/op         120 B/op          4 allocs/op
    PASS
    ok      command-line-arguments  2.190s
    
zitryss
  • 148
  • 1
  • 8