Created
July 16, 2014 20:11
-
-
Save tux21b/adb6d8e731763e4af31a to your computer and use it in GitHub Desktop.
stupid allocations...
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
//+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