Skip to content

Commit

Permalink
Fix benchmarks; delete cbor, simple, binc (#17)
Browse files Browse the repository at this point in the history
* Fixed all of the benchmark code to work again.
* Updated documentation with correct package paths
* Deleted protocols we don't need
   cbor
   * simple
   * binc
* Removed a bunch of workarounds for old Go versions
* Removed some redundant documentation
  • Loading branch information
swenson committed Dec 9, 2022
1 parent 810d5fd commit c68e948
Show file tree
Hide file tree
Showing 42 changed files with 388 additions and 4,977 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
venv
86 changes: 14 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
[![Sourcegraph](https://sourcegraph.com/github.com/ugorji/go/-/badge.svg?v=4)](https://sourcegraph.com/github.com/ugorji/go/-/tree/codec?badge)
[![Build Status](https://travis-ci.org/ugorji/go.svg?branch=master)](https://travis-ci.org/ugorji/go)
[![codecov](https://codecov.io/gh/ugorji/go/branch/master/graph/badge.svg?v=4)](https://codecov.io/gh/ugorji/go)
[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/ugorji/go/codec)
[![rcard](https://goreportcard.com/badge/github.com/ugorji/go/codec?v=4)](https://goreportcard.com/report/github.com/ugorji/go/codec)
[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/ugorji/go/master/LICENSE)
# go-msgpack

# go-codec

This repository contains the `go-codec` library.
This repository contains the `go-msgpack` library.

To install:

Expand All @@ -18,23 +11,13 @@ go get github.com/hashicorp/go-msgpack/codec
# Package Documentation


Package codec provides a High Performance, Feature-Rich Idiomatic Go 1.4+
codec/encoding library for binc, msgpack, cbor, json.
Package codec provides a High Performance, Feature-Rich Idiomatic
codec/encoding library for msgpack, json.

Supported Serialization formats are:

- msgpack: https://github.com/msgpack/msgpack
- binc: http://github.com/ugorji/binc
- cbor: http://cbor.io http://tools.ietf.org/html/rfc7049
- json: http://json.org http://tools.ietf.org/html/rfc7159
- simple:

This package will carefully use 'package unsafe' for performance reasons in
specific places. You can build without unsafe use by passing the safe or
appengine tag i.e. 'go install -tags=safe ...'. Note that unsafe is only
supported for the last 4 go releases e.g. current go release is go 1.12, so
we support unsafe use only from go 1.9+ . This is because supporting unsafe
requires knowledge of implementation details.

For detailed usage information, read the primer at
http://ugorji.net/blog/go-codec-primer .
Expand All @@ -45,12 +28,9 @@ standard library (ie json, xml, gob, etc).
Rich Feature Set includes:

- Simple but extremely powerful and feature-rich API
- Support for go1.4 and above, while selectively using newer APIs for later releases
- Excellent code coverage ( > 90% )
- Very High Performance.
Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
- Careful selected use of 'unsafe' for targeted performance gains.
100% mode exists where 'unsafe' is not used at all.
- Lock-free (sans mutex) concurrency for scaling to 100's of cores
- In-place updates during decode, with option to zero value in maps and slices prior to decode
- Coerce types where appropriate
Expand All @@ -76,9 +56,9 @@ Rich Feature Set includes:
- Comprehensive support for anonymous fields
- Fast (no-reflection) encoding/decoding of common maps and slices
- Code-generation for faster performance.
- Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
- Support binary (e.g. messagepack) and text (e.g. json) formats
- Support indefinite-length formats to enable true streaming
(for formats which support it e.g. json, cbor)
(for formats which support it e.g. json)
- Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes.
This mostly applies to maps, where iteration order is non-deterministic.
- NIL in data stream decoded as zero value
Expand Down Expand Up @@ -166,23 +146,21 @@ Sample usage model:
```go
// create and configure Handle
var (
bh codec.BincHandle
mh codec.MsgpackHandle
ch codec.CborHandle
)

mh.MapType = reflect.TypeOf(map[string]interface{}(nil))

// configure extensions
// e.g. for msgpack, define functions and enable Time support for tag 1
// mh.SetExt(reflect.TypeOf(time.Time{}), 1, myExt)
mh.SetExt(reflect.TypeOf(time.Time{}), 1, myExt)

// create and use decoder/encoder
var (
r io.Reader
w io.Writer
b []byte
h = &bh // or mh to use msgpack
h = &mh
)

dec = codec.NewDecoder(r, h)
Expand Down Expand Up @@ -235,11 +213,14 @@ You can run the tag 'safe' to run tests or build in safe mode. e.g.
## Running Benchmarks

```
cd bench
cd codec/bench
./bench.sh -d
./bench.sh -c
./bench.sh -s
go test -bench . -benchmem -benchtime 1s
```

Please see http://github.com/ugorji/go-codec-bench .
Please see http://github.com/hashicorp/go-codec-bench .


## Caveats
Expand All @@ -251,48 +232,9 @@ decoding
- func, complex numbers, unsafe pointers
- unexported and not embedded
- unexported and embedded and not struct kind
- unexported and embedded pointers (from go1.10)
- unexported and embedded pointers

Every other field in a struct will be encoded/decoded.

Embedded fields are encoded as if they exist in the top-level struct, with
some caveats. See Encode documentation.

## Exported Package API

```go
const CborStreamBytes byte = 0x5f ...
const GenVersion = 10
var GoRpc goRpc
var MsgpackSpecRpc msgpackSpecRpc
func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver)
func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver)
type BasicHandle struct{ ... }
type BincHandle struct{ ... }
type BytesExt interface{ ... }
type CborHandle struct{ ... }
type DecodeOptions struct{ ... }
type Decoder struct{ ... }
func NewDecoder(r io.Reader, h Handle) *Decoder
func NewDecoderBytes(in []byte, h Handle) *Decoder
type EncodeOptions struct{ ... }
type Encoder struct{ ... }
func NewEncoder(w io.Writer, h Handle) *Encoder
func NewEncoderBytes(out *[]byte, h Handle) *Encoder
type Ext interface{ ... }
type Handle interface{ ... }
type InterfaceExt interface{ ... }
type JsonHandle struct{ ... }
type MapBySlice interface{ ... }
type MissingFielder interface{ ... }
type MsgpackHandle struct{ ... }
type MsgpackSpecRpcMultiArgs []interface{}
type RPCOptions struct{ ... }
type Raw []byte
type RawExt struct{ ... }
type Rpc interface{ ... }
type Selfer interface{ ... }
type SimpleHandle struct{ ... }
type TypeInfos struct{ ... }
func NewTypeInfos(tags []string) *TypeInfos
```
9 changes: 2 additions & 7 deletions codec/bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@

This is a comparison of different binary and text encodings.

We compare the codecs provided by github.com/ugorji/go/codec package,
We compare the codecs provided by github.com/hashicorp/go-msgpack/v2/codec package,
against other libraries:

[github.com/ugorji/go/codec](http://github.com/ugorji/go) provides:
[github.com/go-msgpack/go-msgpack/v2/codec](http://github.com/hashicorp/go-msgpack/v2/codec) provides:

- msgpack: [http://github.com/msgpack/msgpack]
- binc: [http://github.com/ugorji/binc]
- cbor: [http://cbor.io] [http://tools.ietf.org/html/rfc7049]
- simple:
- json: [http://json.org] [http://tools.ietf.org/html/rfc7159]

Other codecs compared include:
Expand All @@ -19,11 +16,9 @@ Other codecs compared include:
- [gopkg.in/mgo.v2/bson](http://gopkg.in/mgo.v2/bson)
- [github.com/davecgh/go-xdr/xdr2](https://godoc.org/github.com/davecgh/go-xdr/xdr)
- [github.com/Sereal/Sereal/Go/sereal](https://godoc.org/github.com/Sereal/Sereal/Go/sereal)
- [code.google.com/p/cbor/go](http://code.google.com/p/cbor/go)
- [github.com/tinylib/msgp](http://github.com/tinylib/msgp)
- [github.com/tinylib/msgp](http://godoc.org/github.com/tinylib/msgp)
- [github.com/pquerna/ffjson/ffjson](http://godoc.org/github.com/pquerna/ffjson/ffjson)
- [bitbucket.org/bodhisnarkva/cbor/go](http://godoc.org/bitbucket.org/bodhisnarkva/cbor/go)
- [github.com/json-iterator/go](http://godoc.org/github.com/json-iterator/go)
- [github.com/mailru/easyjson](http://godoc.org/github.com/mailru/easyjson)

Expand Down
26 changes: 16 additions & 10 deletions codec/bench/bench.sh
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
#!/bin/bash

# download the code and all its dependencies
# download the code and all its dependencies
_go_get() {
go get -u \
"github.com/ugorji/go/codec" "github.com/ugorji/go/codec"/codecgen \
github.com/tinylib/msgp/msgp github.com/tinylib/msgp \
github.com/pquerna/ffjson/ffjson github.com/pquerna/ffjson \
github.com/hashicorp/go-msgpack/v2/codec \
github.com/hashicorp/go-msgpack/v2/codec/codecgen \
github.com/tinylib/msgp/msgp \
github.com/tinylib/msgp \
github.com/pquerna/ffjson/ffjson \
github.com/pquerna/ffjson \
github.com/Sereal/Sereal/Go/sereal \
bitbucket.org/bodhisnarkva/cbor/go \
github.com/davecgh/go-xdr/xdr2 \
gopkg.in/mgo.v2/bson \
gopkg.in/vmihailenco/msgpack.v2 \
github.com/json-iterator/go \
github.com/mailru/easyjson/...
go install github.com/tinylib/msgp@latest
go get github.com/mailru/easyjson && go install github.com/mailru/easyjson/...@latest
go install github.com/pquerna/ffjson@latest

}

# add generated tag to the top of each file
Expand Down Expand Up @@ -45,7 +51,7 @@ _gen() {
echo "easyjson ... " &&
easyjson -all -no_std_marshalers -omit_empty -output_filename e9.go v.go &&
_prependbt e9.go values_easyjson${zsfx} &&
echo "ffjson ... " &&
echo "ffjson ... " &&
ffjson -force-regenerate -reset-fields -w f9.go v.go &&
_prependbt f9.go values_ffjson${zsfx} &&
sed -i '' -e 's+ MarshalJSON(+ _MarshalJSON(+g' values_ffjson${zsfx} &&
Expand All @@ -59,11 +65,11 @@ _gen() {
#
# Basically, its a sequence of
# go test -tags "alltests x safe codecgen generated" -bench "CodecSuite or AllSuite or XSuite" -benchmem
#
#
_suite() {
local t="alltests x"
local a=( "" "safe" "codecgen" "codecgen safe")
local b=( "generated" "generated safe")
local a=( "" "codecgen" )
local b=( "generated" )
for i in "${a[@]}"
do
echo ">>>> bench TAGS: '$t $i' SUITE: BenchmarkCodecXSuite"
Expand Down Expand Up @@ -104,4 +110,4 @@ then
else
echo "bench.sh must be run from the directory it resides in"
_usage
fi
fi
70 changes: 4 additions & 66 deletions codec/bench/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"runtime"
"testing"
"time"

"github.com/hashicorp/go-msgpack/v2/codec/internal"
)

// Sample way to run:
Expand Down Expand Up @@ -46,17 +48,14 @@ func benchReinit() {

func benchPreInit() {
benchTs = newTestStruc(benchDepth, testNumRepeatString, true, !testSkipIntf, benchMapStringKeyOnly)
approxSize = approxDataSize(reflect.ValueOf(benchTs)) * 3 / 2 // multiply by 1.5 to appease msgp, and prevent alloc
approxSize = internal.ApproxDataSize(reflect.ValueOf(benchTs)) * 3 / 2 // multiply by 1.5 to appease msgp, and prevent alloc
// bytesLen := 1024 * 4 * (benchDepth + 1) * (benchDepth + 1)
// if bytesLen < approxSize {
// bytesLen = approxSize
// }

benchCheckers = append(benchCheckers,
benchChecker{"msgpack", fnMsgpackEncodeFn, fnMsgpackDecodeFn},
benchChecker{"binc", fnBincEncodeFn, fnBincDecodeFn},
benchChecker{"simple", fnSimpleEncodeFn, fnSimpleDecodeFn},
benchChecker{"cbor", fnCborEncodeFn, fnCborDecodeFn},
benchChecker{"json", fnJsonEncodeFn, fnJsonDecodeFn},
benchChecker{"std-json", fnStdJsonEncodeFn, fnStdJsonDecodeFn},
benchChecker{"gob", fnGobEncodeFn, fnGobDecodeFn},
Expand Down Expand Up @@ -139,7 +138,7 @@ func doBenchCheck(name string, encfn benchEncFn, decfn benchDecFn) {
decDur := time.Since(tnow)
// if benchCheckDoDeepEqual {
if benchVerify {
err = deepEqual(benchTs, &ts2)
err = internal.DeepEqual(benchTs, &ts2)
if err == nil {
logT(nil, "\t%10s: len: %d bytes,\t encode: %v,\t decode: %v,\tencoded = decoded", name, encLen, encDur, decDur)
} else {
Expand Down Expand Up @@ -205,19 +204,6 @@ func fnBenchmarkDecode(b *testing.B, encName string, ts interface{},
logT(b, "Error encoding benchTs: %s: %v", encName, err)
b.FailNow()
}
if false && benchVerify { // do not do benchVerify during decode
// ts2 := newfn()
ts1 := ts.(*TestStruc)
ts2 := new(TestStruc)
if err = decfn(buf, ts2); err != nil {
logT(b, "BenchVerify: Error decoding benchTs: %s: %v", encName, err)
b.FailNow()
}
if err = deepEqual(ts1, ts2); err != nil {
logT(b, "BenchVerify: Error comparing benchTs: %s: %v", encName, err)
b.FailNow()
}
}
runtime.GC()
b.ResetTimer()
for i := 0; i < b.N; i++ {
Expand All @@ -242,30 +228,6 @@ func fnMsgpackDecodeFn(buf []byte, ts interface{}) error {
return sTestCodecDecode(buf, ts, testMsgpackH, &testMsgpackH.BasicHandle)
}

func fnBincEncodeFn(ts interface{}, bsIn []byte) (bs []byte, err error) {
return sTestCodecEncode(ts, bsIn, fnBenchmarkByteBuf, testBincH, &testBincH.BasicHandle)
}

func fnBincDecodeFn(buf []byte, ts interface{}) error {
return sTestCodecDecode(buf, ts, testBincH, &testBincH.BasicHandle)
}

func fnSimpleEncodeFn(ts interface{}, bsIn []byte) (bs []byte, err error) {
return sTestCodecEncode(ts, bsIn, fnBenchmarkByteBuf, testSimpleH, &testSimpleH.BasicHandle)
}

func fnSimpleDecodeFn(buf []byte, ts interface{}) error {
return sTestCodecDecode(buf, ts, testSimpleH, &testSimpleH.BasicHandle)
}

func fnCborEncodeFn(ts interface{}, bsIn []byte) (bs []byte, err error) {
return sTestCodecEncode(ts, bsIn, fnBenchmarkByteBuf, testCborH, &testCborH.BasicHandle)
}

func fnCborDecodeFn(buf []byte, ts interface{}) error {
return sTestCodecDecode(buf, ts, testCborH, &testCborH.BasicHandle)
}

func fnJsonEncodeFn(ts interface{}, bsIn []byte) (bs []byte, err error) {
return sTestCodecEncode(ts, bsIn, fnBenchmarkByteBuf, testJsonH, &testJsonH.BasicHandle)
}
Expand Down Expand Up @@ -316,18 +278,6 @@ func Benchmark__Msgpack____Encode(b *testing.B) {
fnBenchmarkEncode(b, "msgpack", benchTs, fnMsgpackEncodeFn)
}

func Benchmark__Binc_______Encode(b *testing.B) {
fnBenchmarkEncode(b, "binc", benchTs, fnBincEncodeFn)
}

func Benchmark__Simple_____Encode(b *testing.B) {
fnBenchmarkEncode(b, "simple", benchTs, fnSimpleEncodeFn)
}

func Benchmark__Cbor_______Encode(b *testing.B) {
fnBenchmarkEncode(b, "cbor", benchTs, fnCborEncodeFn)
}

func Benchmark__Json_______Encode(b *testing.B) {
fnBenchmarkEncode(b, "json", benchTs, fnJsonEncodeFn)
}
Expand All @@ -350,18 +300,6 @@ func Benchmark__Msgpack____Decode(b *testing.B) {
fnBenchmarkDecode(b, "msgpack", benchTs, fnMsgpackEncodeFn, fnMsgpackDecodeFn, fnBenchNewTs)
}

func Benchmark__Binc_______Decode(b *testing.B) {
fnBenchmarkDecode(b, "binc", benchTs, fnBincEncodeFn, fnBincDecodeFn, fnBenchNewTs)
}

func Benchmark__Simple_____Decode(b *testing.B) {
fnBenchmarkDecode(b, "simple", benchTs, fnSimpleEncodeFn, fnSimpleDecodeFn, fnBenchNewTs)
}

func Benchmark__Cbor_______Decode(b *testing.B) {
fnBenchmarkDecode(b, "cbor", benchTs, fnCborEncodeFn, fnCborDecodeFn, fnBenchNewTs)
}

func Benchmark__Json_______Decode(b *testing.B) {
fnBenchmarkDecode(b, "json", benchTs, fnJsonEncodeFn, fnJsonDecodeFn, fnBenchNewTs)
}
Expand Down
Loading

0 comments on commit c68e948

Please sign in to comment.