Skip to content

Instantly share code, notes, and snippets.

@tux21b
Created July 16, 2014 20:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tux21b/adb6d8e731763e4af31a to your computer and use it in GitHub Desktop.
Save tux21b/adb6d8e731763e4af31a to your computer and use it in GitHub Desktop.
stupid allocations...
//+build ignore
package gocql
import (
"fmt"
"io"
"io/ioutil"
"sync"
"testing"
)
const (
defaultFrameSize = 4096
headerSize = 8
)
var framePool = sync.Pool{
New: func() interface{} {
return make(frame, headerSize, defaultFrameSize)
},
}
type frame []byte
func NewFrame() frame {
return make(frame, headerSize, defaultFrameSize)
}
func (f frame) WriteShort(v uint16) frame {
f, m := f.grow(2)
f[m] = byte(v >> 8)
f[m+1] = byte(v)
return f
}
func (f *frame) WriteShort2(v uint16) {
m := f.grow2(2)
(*f)[m] = byte(v >> 8)
(*f)[m+1] = byte(v)
}
func (f frame) WriteString(v string) frame {
f = f.WriteShort(uint16(len(v)))
f, m := f.grow(len(v))
copy(f[m:], v)
return f
}
func (f *frame) WriteString2(v string) {
f.WriteShort2(uint16(len(v)))
m := f.grow2(len(v))
copy((*f)[m:], v)
}
func (f frame) WriteInt(v int32) frame {
x := uint32(v)
f, m := f.grow(4)
f[m] = byte(x >> 24)
f[m+1] = byte(x >> 16)
f[m+2] = byte(x >> 8)
f[m+3] = byte(x)
return f
}
func (f frame) WriteTo(w io.Writer) (n int64, err error) {
m, e := w.Write(f)
return int64(m), e
}
func (f frame) grow(n int) (frame, int) {
m := len(f)
if len(f)+n > cap(f) {
fmt.Println("growing...")
nf := make([]byte, 2*cap(f)+n)
copy(nf, f)
//framePool.Put(f[:headerSize])
f = nf
}
f = f[:m+n]
return f, m
}
func (f *frame) grow2(n int) int {
m := len(*f)
if len(*f)+n > cap(*f) {
fmt.Println("growing...")
nf := make([]byte, 2*cap(*f)+n)
copy(nf, *f)
//framePool.Put(f[:headerSize])
*f = nf
}
*f = (*f)[:m+n]
return m
}
func Query1(qry string) {
f := NewFrame()
f = f.WriteString(qry)
f = f.WriteInt(42)
f.WriteTo(ioutil.Discard)
}
func Query2(qry string) {
f := make(frame, headerSize, defaultFrameSize)
f = f.WriteString(qry)
f = f.WriteInt(42)
ioutil.Discard.Write([]byte(f))
}
func Query3(qry string, f frame) {
copy(f, qry)
ioutil.Discard.Write(f)
}
func Query4(qry string) {
x := framePool.Get()
f := x.(frame)
f = f.WriteString(qry)
f = f.WriteInt(42)
ioutil.Discard.Write(f)
framePool.Put(x)
}
func Query5(qry string) {
f, x := obtainFrame()
f = f.WriteString("foo")
f = f.WriteInt(42)
ioutil.Discard.Write(f)
discardFrame(f, x)
}
func Query6(qry string) {
f, x := obtainFrame()
f.WriteString2("foo")
f = f.WriteInt(42)
ioutil.Discard.Write(f)
discardFrame(f, x)
}
func obtainFrame() (f frame, x interface{}) {
x = framePool.Get()
f = x.(frame)
return
}
func discardFrame(f frame, x interface{}) {
if x == nil || &(x.(frame)[0]) != &f[0] {
framePool.Put(f)
}
framePool.Put(x)
}
func BenchmarkQuery1(b *testing.B) {
for i := 0; i < b.N; i++ {
Query1("foo")
}
}
func BenchmarkQuery2(b *testing.B) {
for i := 0; i < b.N; i++ {
Query2("foo")
}
}
func BenchmarkQuery3(b *testing.B) {
f := make(frame, headerSize, defaultFrameSize)
for i := 0; i < b.N; i++ {
Query3("foo", f)
f = f[:headerSize]
}
}
func BenchmarkQuery4(b *testing.B) {
for i := 0; i < b.N; i++ {
Query4("foo")
}
}
func BenchmarkQuery5(b *testing.B) {
for i := 0; i < b.N; i++ {
Query5("foo")
}
}
func BenchmarkQuery6(b *testing.B) {
for i := 0; i < b.N; i++ {
Query6("foo")
}
}
/*
PASS
BenchmarkQuery1 1000000 2693 ns/op 4096 B/op 1 allocs/op
BenchmarkQuery2 1000000 2686 ns/op 4096 B/op 1 allocs/op
BenchmarkQuery3 100000000 11.7 ns/op 0 B/op 0 allocs/op
BenchmarkQuery4 20000000 83.5 ns/op 0 B/op 0 allocs/op
BenchmarkQuery5 20000000 107 ns/op 0 B/op 0 allocs/op
BenchmarkQuery6 10000000 197 ns/op 33 B/op 1 allocs/op
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment