Giter Site home page Giter Site logo

go-interface-benchmark's Introduction

Go Interface Benchmark

After being challenged by a colleague on the performance impacts of using Go's typed interfaces, I wrote this benchmark to determine the (contrived) impacts of their use.

Results

As run on my test machine, with an AMD Athlon II X2 270 @ 3.4GHz, using Go 1.11.

tserkov@github:~$ go version
go version go1.11 linux/amd64
tserkov@github:~$ go test -v -bench=. -benchmem
goos: linux
goarch: amd64
pkg: github.com/tserkov/go-interface-benchmark
BenchmarkWithAlloc-2                    2000000000               0.89 ns/op            0 B/op          0 allocs/op
BenchmarkWithFunc-2                     300000000                4.71 ns/op            0 B/op          0 allocs/op
BenchmarkWithPtrFunc-2                  1000000000               2.38 ns/op            0 B/op          0 allocs/op
BenchmarkWithCastAlloc-2                2000000000               0.89 ns/op            0 B/op          0 allocs/op
BenchmarkWithPtrCastAlloc-2             2000000000               0.88 ns/op            0 B/op          0 allocs/op
BenchmarkWithCastFunc-2                 1000000000               2.06 ns/op            0 B/op          0 allocs/op
BenchmarkWithCastPtrFunc-2              1000000000               2.38 ns/op            0 B/op          0 allocs/op
BenchmarkWithPtrCastFunc-2              1000000000               2.14 ns/op            0 B/op          0 allocs/op
BenchmarkWithPtrCastPtrFunc-2           1000000000               2.88 ns/op            0 B/op          0 allocs/op
BenchmarkWithoutPtrAlloc-2              2000000000               0.59 ns/op            0 B/op          0 allocs/op
BenchmarkWithoutPtrFunc-2               1000000000               2.11 ns/op            0 B/op          0 allocs/op
BenchmarkWithoutPtrPtrFunc-2            500000000                2.38 ns/op            0 B/op          0 allocs/op
BenchmarkWithoutNonPtrAlloc-2           2000000000               0.59 ns/op            0 B/op          0 allocs/op
BenchmarkWithoutNonPtrFunc-2            1000000000               2.06 ns/op            0 B/op          0 allocs/op
BenchmarkWithoutNonPtrPtrFunc-2         1000000000               2.86 ns/op            0 B/op          0 allocs/op
PASS
ok      github.com/tserkov/go-interface-benchmark       32.347s

Analysis

For allocations, we can see that allocating structs into an interfaced-typed variable is slower.

As for actual function calls, well...

Name Variable Type Function Receiver Time
BenchmarkWithoutNonPtrFunc struct Non-pointer 2.06ns
BenchmarkWithCastFunc struct, cast from interface Non-pointer 2.06ns
BenchmarkWithoutPtrFunc *struct Non-pointer 2.11ns
BenchmarkWithPtrCastFunc *struct, cast from interface Non-pointer 2.14ns
BenchmarkWithoutPtrPtrFunc *struct Pointer 2.38ns
BenchmarkWithCastPtrFunc struct, cast from interface Pointer 2.38ns
BenchmarkWithPtrFunc interface Pointer 2.38ns
BenchmarkWithoutNonPtrPtrFunc struct Pointer 2.86ns
BenchmarkWithPtrCastPtrFunc *struct, cast from interface Pointer 2.88ns
BenchmarkWithFunc interface Non-pointer 4.71ns

The slowest calls were those to a non-pointer receiver function on an interface-typed variable. Which is one of the most common signatures (ie. net/http).

The fastest in this benchmark was calling a non-pointer receiver function on a struct-typed variable. However, in the real world, this would likely not be true in most non-trival cases, since the receiver struct is copied for the function. There's also likely so compiler optimizations taking place here that I'm not aware of.

In reality, calling a pointer receiver function on a pointer to struct would probably be the fastest.

One discrepancy I'm not sure about is how a struct-typed variable, cast from an interface, with a pointer receiver function is somehow faster than the exact same call without the intermediate casting stage.

For a bit more context in what the CPU is doing even outside of Go's bytecode, be sure to check out latency numbers every programmer should know.

Conclusion

In practice, if your usage is in a hot spot, you'll want to call functions on struct-typed variables. The performance impact of the function having a pointer receiver to the struct will depend on what the function is doing.

However, if your usage is not in a hot spot, keep in mind that a nanosecond (ns) is 1 billionth of a second. So even with the worst-case scenario of calling a non-pointer receiver function on an interface-typed variable, the cost is only ~4.7 billionths of a second. Don't let overzealous or premature optimization prevent your package from becoming readable or testable.

go-interface-benchmark's People

Stargazers

 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.