Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix benchmarks; delete cbor, simple, binc #17

Merged
merged 1 commit into from
Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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