Skip to content

Instantly share code, notes, and snippets.

@joetifa2003
Last active November 25, 2022 15:08
Show Gist options
  • Save joetifa2003/e783978b053b79222839e1ff76f7abfe to your computer and use it in GitHub Desktop.
Save joetifa2003/e783978b053b79222839e1ff76f7abfe to your computer and use it in GitHub Desktop.
Golang array field slowing struct
package main
import "unsafe"
type ValueType int
const (
VALUE_INT ValueType = iota
VALUE_ARRAY
)
type ValueWithoutArray struct {
VType ValueType
IntV int
}
type ValueWithSlice struct {
VType ValueType
IntV int
ArrayV []ValueWithSlice
}
type ValueWithSlicePointer struct {
VType ValueType
IntV int
ArrayV *[]ValueWithSlice
}
type ValueWithUnsafePointer struct {
VType ValueType
IntV int
ArrayV unsafe.Pointer
}
type Stack[T any] struct {
stack []T
}
func NewStack[T any]() Stack[T] {
return Stack[T]{
stack: make([]T, 0, 1024),
}
}
func (s *Stack[T]) Push(v T) {
s.stack = append(s.stack, v)
}
func (s *Stack[T]) Pop() T {
lastElement := s.stack[len(s.stack)-1]
s.stack = s.stack[:len(s.stack)-1]
return lastElement
}
package main
import "testing"
// Benchmark results
// As you can see i only use the int field
// The array in the ValueWithArray is always nil
// goos: linux
// goarch: amd64
// cpu: Intel(R) Core(TM) i7-4710HQ CPU @ 2.50GHz
// BenchmarkWithoutArray-8 201895 5001 ns/op 0 B/op 0 allocs/op
// BenchmarkWithSlice-8 81074 14222 ns/op 0 B/op 0 allocs/op
// BenchmarkValueWithSlicePointer-8 187293 5929 ns/op 0 B/op 0 allocs/op
// BenchmarkValueWithUnsafePointer-8 186288 5727 ns/op 0 B/op 0 allocs/op
// PASS
// ok windlang-preg-gist 4.686s
const TIMES = 1000
func BenchmarkWithoutArray(b *testing.B) {
stack := NewStack[ValueWithoutArray]()
for i := 0; i < b.N; i++ {
for j := 0; j < TIMES; j++ {
stack.Push(ValueWithoutArray{VType: VALUE_INT, IntV: j})
}
for j := 0; j < TIMES; j++ {
stack.Pop()
}
}
}
func BenchmarkWithSlice(b *testing.B) {
stack := NewStack[ValueWithSlice]()
for i := 0; i < b.N; i++ {
for j := 0; j < TIMES; j++ {
stack.Push(ValueWithSlice{VType: VALUE_INT, IntV: j})
}
for j := 0; j < TIMES; j++ {
stack.Pop()
}
}
}
func BenchmarkValueWithSlicePointer(b *testing.B) {
stack := NewStack[ValueWithSlicePointer]()
for i := 0; i < b.N; i++ {
for j := 0; j < TIMES; j++ {
stack.Push(ValueWithSlicePointer{VType: VALUE_INT, IntV: j})
}
for j := 0; j < TIMES; j++ {
stack.Pop()
}
}
}
func BenchmarkValueWithUnsafePointer(b *testing.B) {
stack := NewStack[ValueWithUnsafePointer]()
for i := 0; i < b.N; i++ {
for j := 0; j < TIMES; j++ {
stack.Push(ValueWithUnsafePointer{VType: VALUE_INT, IntV: j})
}
for j := 0; j < TIMES; j++ {
stack.Pop()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment