Last active
August 29, 2015 14:03
-
-
Save edsrzf/4759ee8e5e26d1b12330 to your computer and use it in GitHub Desktop.
Benchmarking value vs. pointer receiver for a 56-byte struct
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/binary" | |
"testing" | |
) | |
var little = binary.LittleEndian | |
type Segment struct { | |
Data []uint8 | |
} | |
type Object struct { | |
Segment *Segment | |
off int // in bytes | |
length int | |
datasz int // in bytes | |
ptrs int | |
typ uint8 | |
flags uint | |
} | |
func (p Object) valueListData(i int, sz int) []byte { | |
if i < 0 || i >= p.length { | |
return nil | |
} | |
if sz > p.datasz*8 { | |
return nil | |
} | |
off := p.off + i*(p.datasz+p.ptrs*8) | |
return p.Segment.Data[off:] | |
} | |
func (p *Object) pointerListData(i int, sz int) []byte { | |
if i < 0 || i >= p.length { | |
return nil | |
} | |
if sz > p.datasz*8 { | |
return nil | |
} | |
off := p.off + i*(p.datasz+p.ptrs*8) | |
return p.Segment.Data[off:] | |
} | |
type Int8List Object | |
type UInt8List Object | |
func (p Int8List) ValueAt(i int) int8 { return int8(UInt8List(p).ValueAt(i)) } | |
func (p UInt8List) ValueAt(i int) uint8 { | |
if data := Object(p).valueListData(i, 8); data != nil { | |
return data[0] | |
} else { | |
return 0 | |
} | |
} | |
func (p *Int8List) PointerAt(i int) int8 { return int8((*UInt8List)(p).PointerAt(i)) } | |
func (p *UInt8List) PointerAt(i int) uint8 { | |
if data := (*Object)(p).pointerListData(i, 8); data != nil { | |
return data[0] | |
} else { | |
return 0 | |
} | |
} | |
type Struct Object | |
func (p Struct) ValueGet8(off int) uint8 { | |
if off < p.datasz { | |
return p.Segment.Data[uint(p.off)+uint(off)] | |
} else { | |
return 0 | |
} | |
} | |
func (p *Struct) PointerGet8(off int) uint8 { | |
if off < p.datasz { | |
return p.Segment.Data[uint(p.off)+uint(off)] | |
} else { | |
return 0 | |
} | |
} | |
func (p Struct) ValueGet64(off int) uint64 { | |
if off < p.datasz { | |
return little.Uint64(p.Segment.Data[uint(p.off)+uint(off):]) | |
} else { | |
return 0 | |
} | |
} | |
func (p *Struct) PointerGet64(off int) uint64 { | |
if off < p.datasz { | |
return little.Uint64(p.Segment.Data[uint(p.off)+uint(off):]) | |
} else { | |
return 0 | |
} | |
} | |
var seg = Segment{Data: make([]byte, 1)} | |
func BenchmarkValueGet8(b *testing.B) { | |
var o Struct | |
for i := 0; i < b.N; i++ { | |
o.ValueGet8(0) | |
} | |
} | |
func BenchmarkPointerGet8(b *testing.B) { | |
var o Struct | |
for i := 0; i < b.N; i++ { | |
o.PointerGet8(0) | |
} | |
} | |
func BenchmarkValueGet64(b *testing.B) { | |
var o Struct | |
for i := 0; i < b.N; i++ { | |
o.ValueGet64(0) | |
} | |
} | |
func BenchmarkPointerGet64(b *testing.B) { | |
var o Struct | |
for i := 0; i < b.N; i++ { | |
o.PointerGet64(0) | |
} | |
} | |
func BenchmarkValueAt(b *testing.B) { | |
var l Int8List | |
for i := 0; i < b.N; i++ { | |
l.ValueAt(0) | |
} | |
} | |
func BenchmarkPointerAt(b *testing.B) { | |
var l Int8List | |
for i := 0; i < b.N; i++ { | |
l.PointerAt(0) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment