This benchmark demonstrates how Go generics speedup scenarios where boxing can be avoided.
- What is boxing?: a summary of boxing
- The example: an exemplar case
- The benchmark: how does it stack up?
- Key takeaways: what it all means
In general, the term boxing refers to wrapping a value with some container, aka, "putting it inside a box." For the purposes of this page, the term "boxing" will refer to wrapping some value in Golang with the empty interface, ex.:
x := int(0)
i := interface{}(x)
Generics can be used to eliminate the need for boxing in many situations, which we will highlight with List[T]
.
This page describes how to run BenchmarkBoxing
, a Go-based benchmark that benchmarks lists from the following packages:
./lists/boxed
: definestype List []interface{}
./lists/typed
: definestype IntList []int
./lists/generic
: definestype List[T any] []T
In order to determine the impact of boxing, we will run a Go benchmark that adds random integers to instances of a boxed.List
, typed.IntList
, and generic.List[int]
:
docker run -it --rm go-generics-the-hard-way \
go test -bench Boxing -run Boxing -benchmem -count 5 -v ./06-benchmarks
The following table was generated by piping the above command to hack/b2md.py -t boxing
and represents an average across the total number of benchmarks determined by the -count
flag:
List type | Number of types | Operations | ns/op | Bytes/op | Allocs/op |
---|---|---|---|---|---|
Boxed | 1 | 28639768.6 | 49.42 | 100.4 | 0 |
Generic | 1 | 217233399 | 8.31 | 45.4 | 0 |
Typed | 1 | 300006311.8 | 8.49 | 43.4 | 0 |
A few, key takeaways:
- On average the implementation of
List[T any]
was more performant than the boxed list:- operations were 10x faster
- consumed half the memory
- The performance improvements were the result of removing the need to box the integer values
Next: Build times