summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/hashicorp/go-msgpack/codec/bench_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/go-msgpack/codec/bench_test.go')
-rw-r--r--vendor/github.com/hashicorp/go-msgpack/codec/bench_test.go319
1 files changed, 319 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/go-msgpack/codec/bench_test.go b/vendor/github.com/hashicorp/go-msgpack/codec/bench_test.go
new file mode 100644
index 000000000..4d437035e
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-msgpack/codec/bench_test.go
@@ -0,0 +1,319 @@
+// Copyright (c) 2012, 2013 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a BSD-style license found in the LICENSE file.
+
+package codec
+
+import (
+ "bytes"
+ "encoding/gob"
+ "encoding/json"
+ "flag"
+ "fmt"
+ "reflect"
+ "runtime"
+ "testing"
+ "time"
+)
+
+// Sample way to run:
+// go test -bi -bv -bd=1 -benchmem -bench=.
+
+var (
+ _ = fmt.Printf
+ benchTs *TestStruc
+
+ approxSize int
+
+ benchDoInitBench bool
+ benchVerify bool
+ benchUnscientificRes bool = false
+ //depth of 0 maps to ~400bytes json-encoded string, 1 maps to ~1400 bytes, etc
+ //For depth>1, we likely trigger stack growth for encoders, making benchmarking unreliable.
+ benchDepth int
+ benchInitDebug bool
+ benchCheckers []benchChecker
+)
+
+type benchEncFn func(interface{}) ([]byte, error)
+type benchDecFn func([]byte, interface{}) error
+type benchIntfFn func() interface{}
+
+type benchChecker struct {
+ name string
+ encodefn benchEncFn
+ decodefn benchDecFn
+}
+
+func benchInitFlags() {
+ flag.BoolVar(&benchInitDebug, "bg", false, "Bench Debug")
+ flag.IntVar(&benchDepth, "bd", 1, "Bench Depth: If >1, potential unreliable results due to stack growth")
+ flag.BoolVar(&benchDoInitBench, "bi", false, "Run Bench Init")
+ flag.BoolVar(&benchVerify, "bv", false, "Verify Decoded Value during Benchmark")
+ flag.BoolVar(&benchUnscientificRes, "bu", false, "Show Unscientific Results during Benchmark")
+}
+
+func benchInit() {
+ benchTs = newTestStruc(benchDepth, true)
+ approxSize = approxDataSize(reflect.ValueOf(benchTs))
+ bytesLen := 1024 * 4 * (benchDepth + 1) * (benchDepth + 1)
+ if bytesLen < approxSize {
+ bytesLen = approxSize
+ }
+
+ benchCheckers = append(benchCheckers,
+ benchChecker{"msgpack", fnMsgpackEncodeFn, fnMsgpackDecodeFn},
+ benchChecker{"binc-nosym", fnBincNoSymEncodeFn, fnBincNoSymDecodeFn},
+ benchChecker{"binc-sym", fnBincSymEncodeFn, fnBincSymDecodeFn},
+ benchChecker{"simple", fnSimpleEncodeFn, fnSimpleDecodeFn},
+ benchChecker{"gob", fnGobEncodeFn, fnGobDecodeFn},
+ benchChecker{"json", fnJsonEncodeFn, fnJsonDecodeFn},
+ )
+ if benchDoInitBench {
+ runBenchInit()
+ }
+}
+
+func runBenchInit() {
+ logT(nil, "..............................................")
+ logT(nil, "BENCHMARK INIT: %v", time.Now())
+ logT(nil, "To run full benchmark comparing encodings (MsgPack, Binc, Simple, JSON, GOB, etc), "+
+ "use: \"go test -bench=.\"")
+ logT(nil, "Benchmark: ")
+ logT(nil, "\tStruct recursive Depth: %d", benchDepth)
+ if approxSize > 0 {
+ logT(nil, "\tApproxDeepSize Of benchmark Struct: %d bytes", approxSize)
+ }
+ if benchUnscientificRes {
+ logT(nil, "Benchmark One-Pass Run (with Unscientific Encode/Decode times): ")
+ } else {
+ logT(nil, "Benchmark One-Pass Run:")
+ }
+ for _, bc := range benchCheckers {
+ doBenchCheck(bc.name, bc.encodefn, bc.decodefn)
+ }
+ logT(nil, "..............................................")
+ if benchInitDebug {
+ logT(nil, "<<<<====>>>> depth: %v, ts: %#v\n", benchDepth, benchTs)
+ }
+}
+
+func fnBenchNewTs() interface{} {
+ return new(TestStruc)
+}
+
+func doBenchCheck(name string, encfn benchEncFn, decfn benchDecFn) {
+ runtime.GC()
+ tnow := time.Now()
+ buf, err := encfn(benchTs)
+ if err != nil {
+ logT(nil, "\t%10s: **** Error encoding benchTs: %v", name, err)
+ }
+ encDur := time.Now().Sub(tnow)
+ encLen := len(buf)
+ runtime.GC()
+ if !benchUnscientificRes {
+ logT(nil, "\t%10s: len: %d bytes\n", name, encLen)
+ return
+ }
+ tnow = time.Now()
+ if err = decfn(buf, new(TestStruc)); err != nil {
+ logT(nil, "\t%10s: **** Error decoding into new TestStruc: %v", name, err)
+ }
+ decDur := time.Now().Sub(tnow)
+ logT(nil, "\t%10s: len: %d bytes, encode: %v, decode: %v\n", name, encLen, encDur, decDur)
+}
+
+func fnBenchmarkEncode(b *testing.B, encName string, ts interface{}, encfn benchEncFn) {
+ runtime.GC()
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ _, err := encfn(ts)
+ if err != nil {
+ logT(b, "Error encoding benchTs: %s: %v", encName, err)
+ b.FailNow()
+ }
+ }
+}
+
+func fnBenchmarkDecode(b *testing.B, encName string, ts interface{},
+ encfn benchEncFn, decfn benchDecFn, newfn benchIntfFn,
+) {
+ buf, err := encfn(ts)
+ if err != nil {
+ logT(b, "Error encoding benchTs: %s: %v", encName, err)
+ b.FailNow()
+ }
+ runtime.GC()
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ ts = newfn()
+ if err = decfn(buf, ts); err != nil {
+ logT(b, "Error decoding into new TestStruc: %s: %v", encName, err)
+ b.FailNow()
+ }
+ if benchVerify {
+ if vts, vok := ts.(*TestStruc); vok {
+ verifyTsTree(b, vts)
+ }
+ }
+ }
+}
+
+func verifyTsTree(b *testing.B, ts *TestStruc) {
+ var ts0, ts1m, ts2m, ts1s, ts2s *TestStruc
+ ts0 = ts
+
+ if benchDepth > 0 {
+ ts1m, ts1s = verifyCheckAndGet(b, ts0)
+ }
+
+ if benchDepth > 1 {
+ ts2m, ts2s = verifyCheckAndGet(b, ts1m)
+ }
+ for _, tsx := range []*TestStruc{ts0, ts1m, ts2m, ts1s, ts2s} {
+ if tsx != nil {
+ verifyOneOne(b, tsx)
+ }
+ }
+}
+
+func verifyCheckAndGet(b *testing.B, ts0 *TestStruc) (ts1m *TestStruc, ts1s *TestStruc) {
+ // if len(ts1m.Ms) <= 2 {
+ // logT(b, "Error: ts1m.Ms len should be > 2. Got: %v", len(ts1m.Ms))
+ // b.FailNow()
+ // }
+ if len(ts0.Its) == 0 {
+ logT(b, "Error: ts0.Islice len should be > 0. Got: %v", len(ts0.Its))
+ b.FailNow()
+ }
+ ts1m = ts0.Mtsptr["0"]
+ ts1s = ts0.Its[0]
+ if ts1m == nil || ts1s == nil {
+ logT(b, "Error: At benchDepth 1, No *TestStruc found")
+ b.FailNow()
+ }
+ return
+}
+
+func verifyOneOne(b *testing.B, ts *TestStruc) {
+ if ts.I64slice[2] != int64(3) {
+ logT(b, "Error: Decode failed by checking values")
+ b.FailNow()
+ }
+}
+
+func fnMsgpackEncodeFn(ts interface{}) (bs []byte, err error) {
+ err = NewEncoderBytes(&bs, testMsgpackH).Encode(ts)
+ return
+}
+
+func fnMsgpackDecodeFn(buf []byte, ts interface{}) error {
+ return NewDecoderBytes(buf, testMsgpackH).Decode(ts)
+}
+
+func fnBincEncodeFn(ts interface{}, sym AsSymbolFlag) (bs []byte, err error) {
+ tSym := testBincH.AsSymbols
+ testBincH.AsSymbols = sym
+ err = NewEncoderBytes(&bs, testBincH).Encode(ts)
+ testBincH.AsSymbols = tSym
+ return
+}
+
+func fnBincDecodeFn(buf []byte, ts interface{}, sym AsSymbolFlag) (err error) {
+ tSym := testBincH.AsSymbols
+ testBincH.AsSymbols = sym
+ err = NewDecoderBytes(buf, testBincH).Decode(ts)
+ testBincH.AsSymbols = tSym
+ return
+}
+
+func fnBincNoSymEncodeFn(ts interface{}) (bs []byte, err error) {
+ return fnBincEncodeFn(ts, AsSymbolNone)
+}
+
+func fnBincNoSymDecodeFn(buf []byte, ts interface{}) error {
+ return fnBincDecodeFn(buf, ts, AsSymbolNone)
+}
+
+func fnBincSymEncodeFn(ts interface{}) (bs []byte, err error) {
+ return fnBincEncodeFn(ts, AsSymbolAll)
+}
+
+func fnBincSymDecodeFn(buf []byte, ts interface{}) error {
+ return fnBincDecodeFn(buf, ts, AsSymbolAll)
+}
+
+func fnSimpleEncodeFn(ts interface{}) (bs []byte, err error) {
+ err = NewEncoderBytes(&bs, testSimpleH).Encode(ts)
+ return
+}
+
+func fnSimpleDecodeFn(buf []byte, ts interface{}) error {
+ return NewDecoderBytes(buf, testSimpleH).Decode(ts)
+}
+
+func fnGobEncodeFn(ts interface{}) ([]byte, error) {
+ bbuf := new(bytes.Buffer)
+ err := gob.NewEncoder(bbuf).Encode(ts)
+ return bbuf.Bytes(), err
+}
+
+func fnGobDecodeFn(buf []byte, ts interface{}) error {
+ return gob.NewDecoder(bytes.NewBuffer(buf)).Decode(ts)
+}
+
+func fnJsonEncodeFn(ts interface{}) ([]byte, error) {
+ return json.Marshal(ts)
+}
+
+func fnJsonDecodeFn(buf []byte, ts interface{}) error {
+ return json.Unmarshal(buf, ts)
+}
+
+func Benchmark__Msgpack____Encode(b *testing.B) {
+ fnBenchmarkEncode(b, "msgpack", benchTs, fnMsgpackEncodeFn)
+}
+
+func Benchmark__Msgpack____Decode(b *testing.B) {
+ fnBenchmarkDecode(b, "msgpack", benchTs, fnMsgpackEncodeFn, fnMsgpackDecodeFn, fnBenchNewTs)
+}
+
+func Benchmark__Binc_NoSym_Encode(b *testing.B) {
+ fnBenchmarkEncode(b, "binc", benchTs, fnBincNoSymEncodeFn)
+}
+
+func Benchmark__Binc_NoSym_Decode(b *testing.B) {
+ fnBenchmarkDecode(b, "binc", benchTs, fnBincNoSymEncodeFn, fnBincNoSymDecodeFn, fnBenchNewTs)
+}
+
+func Benchmark__Binc_Sym___Encode(b *testing.B) {
+ fnBenchmarkEncode(b, "binc", benchTs, fnBincSymEncodeFn)
+}
+
+func Benchmark__Binc_Sym___Decode(b *testing.B) {
+ fnBenchmarkDecode(b, "binc", benchTs, fnBincSymEncodeFn, fnBincSymDecodeFn, fnBenchNewTs)
+}
+
+func Benchmark__Simple____Encode(b *testing.B) {
+ fnBenchmarkEncode(b, "simple", benchTs, fnSimpleEncodeFn)
+}
+
+func Benchmark__Simple____Decode(b *testing.B) {
+ fnBenchmarkDecode(b, "simple", benchTs, fnSimpleEncodeFn, fnSimpleDecodeFn, fnBenchNewTs)
+}
+
+func Benchmark__Gob________Encode(b *testing.B) {
+ fnBenchmarkEncode(b, "gob", benchTs, fnGobEncodeFn)
+}
+
+func Benchmark__Gob________Decode(b *testing.B) {
+ fnBenchmarkDecode(b, "gob", benchTs, fnGobEncodeFn, fnGobDecodeFn, fnBenchNewTs)
+}
+
+func Benchmark__Json_______Encode(b *testing.B) {
+ fnBenchmarkEncode(b, "json", benchTs, fnJsonEncodeFn)
+}
+
+func Benchmark__Json_______Decode(b *testing.B) {
+ fnBenchmarkDecode(b, "json", benchTs, fnJsonEncodeFn, fnJsonDecodeFn, fnBenchNewTs)
+}