diff --git a/go.sum b/go.sum index aa01f67..2b2c64c 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,7 @@ github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= @@ -69,6 +70,7 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7 h1:xoIK0ctDddBMnc74udxJYBqlo9Ylnsp1waqjLsnef20= github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= @@ -104,6 +106,7 @@ github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:Udh github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= diff --git a/src/ffjsonvec3/vec3.go b/src/ffjsonvec3/vec3.go new file mode 100644 index 0000000..a10af8f --- /dev/null +++ b/src/ffjsonvec3/vec3.go @@ -0,0 +1,7 @@ +package ffjsonvec3 + +type Vec3 struct { + X float32 `json:"x"` + Y float32 `json:"y"` + Z float32 `json:"z"` +} diff --git a/src/ffjsonvec3/vec3_ffjson.go b/src/ffjsonvec3/vec3_ffjson.go new file mode 100644 index 0000000..aee51f0 --- /dev/null +++ b/src/ffjsonvec3/vec3_ffjson.go @@ -0,0 +1,315 @@ +// Code generated by ffjson . DO NOT EDIT. +// source: vec3.go + +package ffjsonvec3 + +import ( + "bytes" + "fmt" + + fflib "github.com/pquerna/ffjson/fflib/v1" +) + +// MarshalJSON marshal bytes to json - template +func (j *Vec3) MarshalJSON() ([]byte, error) { + var buf fflib.Buffer + if j == nil { + buf.WriteString("null") + return buf.Bytes(), nil + } + err := j.MarshalJSONBuf(&buf) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// MarshalJSONBuf marshal buff to json - template +func (j *Vec3) MarshalJSONBuf(buf fflib.EncodingBuffer) error { + if j == nil { + buf.WriteString("null") + return nil + } + var err error + var obj []byte + _ = obj + _ = err + buf.WriteString(`{"x":`) + fflib.AppendFloat(buf, float64(j.X), 'g', -1, 32) + buf.WriteString(`,"y":`) + fflib.AppendFloat(buf, float64(j.Y), 'g', -1, 32) + buf.WriteString(`,"z":`) + fflib.AppendFloat(buf, float64(j.Z), 'g', -1, 32) + buf.WriteByte('}') + return nil +} + +const ( + ffjtVec3base = iota + ffjtVec3nosuchkey + + ffjtVec3X + + ffjtVec3Y + + ffjtVec3Z +) + +var ffjKeyVec3X = []byte("x") + +var ffjKeyVec3Y = []byte("y") + +var ffjKeyVec3Z = []byte("z") + +// UnmarshalJSON umarshall json - template of ffjson +func (j *Vec3) UnmarshalJSON(input []byte) error { + fs := fflib.NewFFLexer(input) + return j.UnmarshalJSONFFLexer(fs, fflib.FFParse_map_start) +} + +// UnmarshalJSONFFLexer fast json unmarshall - template ffjson +func (j *Vec3) UnmarshalJSONFFLexer(fs *fflib.FFLexer, state fflib.FFParseState) error { + var err error + currentKey := ffjtVec3base + _ = currentKey + tok := fflib.FFTok_init + wantedTok := fflib.FFTok_init + +mainparse: + for { + tok = fs.Scan() + // println(fmt.Sprintf("debug: tok: %v state: %v", tok, state)) + if tok == fflib.FFTok_error { + goto tokerror + } + + switch state { + + case fflib.FFParse_map_start: + if tok != fflib.FFTok_left_bracket { + wantedTok = fflib.FFTok_left_bracket + goto wrongtokenerror + } + state = fflib.FFParse_want_key + continue + + case fflib.FFParse_after_value: + if tok == fflib.FFTok_comma { + state = fflib.FFParse_want_key + } else if tok == fflib.FFTok_right_bracket { + goto done + } else { + wantedTok = fflib.FFTok_comma + goto wrongtokenerror + } + + case fflib.FFParse_want_key: + // json {} ended. goto exit. woo. + if tok == fflib.FFTok_right_bracket { + goto done + } + if tok != fflib.FFTok_string { + wantedTok = fflib.FFTok_string + goto wrongtokenerror + } + + kn := fs.Output.Bytes() + if len(kn) <= 0 { + // "" case. hrm. + currentKey = ffjtVec3nosuchkey + state = fflib.FFParse_want_colon + goto mainparse + } else { + switch kn[0] { + + case 'x': + + if bytes.Equal(ffjKeyVec3X, kn) { + currentKey = ffjtVec3X + state = fflib.FFParse_want_colon + goto mainparse + } + + case 'y': + + if bytes.Equal(ffjKeyVec3Y, kn) { + currentKey = ffjtVec3Y + state = fflib.FFParse_want_colon + goto mainparse + } + + case 'z': + + if bytes.Equal(ffjKeyVec3Z, kn) { + currentKey = ffjtVec3Z + state = fflib.FFParse_want_colon + goto mainparse + } + + } + + if fflib.SimpleLetterEqualFold(ffjKeyVec3Z, kn) { + currentKey = ffjtVec3Z + state = fflib.FFParse_want_colon + goto mainparse + } + + if fflib.SimpleLetterEqualFold(ffjKeyVec3Y, kn) { + currentKey = ffjtVec3Y + state = fflib.FFParse_want_colon + goto mainparse + } + + if fflib.SimpleLetterEqualFold(ffjKeyVec3X, kn) { + currentKey = ffjtVec3X + state = fflib.FFParse_want_colon + goto mainparse + } + + currentKey = ffjtVec3nosuchkey + state = fflib.FFParse_want_colon + goto mainparse + } + + case fflib.FFParse_want_colon: + if tok != fflib.FFTok_colon { + wantedTok = fflib.FFTok_colon + goto wrongtokenerror + } + state = fflib.FFParse_want_value + continue + case fflib.FFParse_want_value: + + if tok == fflib.FFTok_left_brace || tok == fflib.FFTok_left_bracket || tok == fflib.FFTok_integer || tok == fflib.FFTok_double || tok == fflib.FFTok_string || tok == fflib.FFTok_bool || tok == fflib.FFTok_null { + switch currentKey { + + case ffjtVec3X: + goto handle_X + + case ffjtVec3Y: + goto handle_Y + + case ffjtVec3Z: + goto handle_Z + + case ffjtVec3nosuchkey: + err = fs.SkipField(tok) + if err != nil { + return fs.WrapErr(err) + } + state = fflib.FFParse_after_value + goto mainparse + } + } else { + goto wantedvalue + } + } + } + +handle_X: + + /* handler: j.X type=float32 kind=float32 quoted=false*/ + + { + if tok != fflib.FFTok_double && tok != fflib.FFTok_integer && tok != fflib.FFTok_null { + return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for float32", tok)) + } + } + + { + + if tok == fflib.FFTok_null { + + } else { + + tval, err := fflib.ParseFloat(fs.Output.Bytes(), 32) + + if err != nil { + return fs.WrapErr(err) + } + + j.X = float32(tval) + + } + } + + state = fflib.FFParse_after_value + goto mainparse + +handle_Y: + + /* handler: j.Y type=float32 kind=float32 quoted=false*/ + + { + if tok != fflib.FFTok_double && tok != fflib.FFTok_integer && tok != fflib.FFTok_null { + return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for float32", tok)) + } + } + + { + + if tok == fflib.FFTok_null { + + } else { + + tval, err := fflib.ParseFloat(fs.Output.Bytes(), 32) + + if err != nil { + return fs.WrapErr(err) + } + + j.Y = float32(tval) + + } + } + + state = fflib.FFParse_after_value + goto mainparse + +handle_Z: + + /* handler: j.Z type=float32 kind=float32 quoted=false*/ + + { + if tok != fflib.FFTok_double && tok != fflib.FFTok_integer && tok != fflib.FFTok_null { + return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for float32", tok)) + } + } + + { + + if tok == fflib.FFTok_null { + + } else { + + tval, err := fflib.ParseFloat(fs.Output.Bytes(), 32) + + if err != nil { + return fs.WrapErr(err) + } + + j.Z = float32(tval) + + } + } + + state = fflib.FFParse_after_value + goto mainparse + +wantedvalue: + return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok)) +wrongtokenerror: + return fs.WrapErr(fmt.Errorf("ffjson: wanted token: %v, but got token: %v output=%s", wantedTok, tok, fs.Output.String())) +tokerror: + if fs.BigError != nil { + return fs.WrapErr(fs.BigError) + } + err = fs.Error.ToError() + if err != nil { + return fs.WrapErr(err) + } + panic("ffjson-generated: unreachable, please report bug.") +done: + + return nil +} diff --git a/src/vec3_test.go b/src/vec3_test.go index 4b1f584..5a80c86 100644 --- a/src/vec3_test.go +++ b/src/vec3_test.go @@ -8,32 +8,51 @@ import ( "github.com/francoispqt/gojay" jsoniter "github.com/json-iterator/go" "github.com/pquerna/ffjson/ffjson" + "xinu.tv/rustperf/src/ffjsonvec3" ) type testFunc struct { name string - f func([]Vec3) ([]byte, error) + f func(start, stop func(), vs []Vec3) ([]byte, error) } var encodeFuncs = []testFunc{ - {"HandRolled", HandRolled}, - {"stdlib", func(vs []Vec3) ([]byte, error) { + {"HandRolled", func(_, _ func(), vs []Vec3) ([]byte, error) { + return HandRolled(vs) + }}, + {"stdlib", func(_, _ func(), vs []Vec3) ([]byte, error) { return json.Marshal(vs) }}, - {"ffjson", func(vs []Vec3) ([]byte, error) { + {"ffjsonvec3", func(start, stop func(), vs []Vec3) ([]byte, error) { + stop() + var vecs []ffjsonvec3.Vec3 + for _, v := range vs { + v := ffjsonvec3.Vec3{ + X: v.X, + Y: v.Y, + Z: v.Z, + } + vecs = append(vecs, v) + } + start() + + return ffjson.Marshal(vecs) + }}, + {"ffjson", func(_, _ func(), vs []Vec3) ([]byte, error) { return ffjson.Marshal(vs) }}, - {"iterator", func(vs []Vec3) ([]byte, error) { + {"iterator", func(_, _ func(), vs []Vec3) ([]byte, error) { var js = jsoniter.ConfigCompatibleWithStandardLibrary return js.Marshal(vs) }}, - {"gojay", func(vs []Vec3) ([]byte, error) { + {"gojay", func(start, stop func(), vs []Vec3) ([]byte, error) { + stop() var vecs Vec3Slice for _, v := range vs { v := v vecs = append(vecs, &v) } - + start() return gojay.Marshal(&vecs) }}, } @@ -46,7 +65,9 @@ func TestVec3ToJSON(t *testing.T) { for _, ts := range encodeFuncs { t.Run(ts.name, func(t *testing.T) { - got, err := ts.f(vecs) + stop := func() {} + start := func() {} + got, err := ts.f(start, stop, vecs) if err != nil { t.Fatalf("Failed to marshal: %v", err) } @@ -69,8 +90,10 @@ func BenchmarkVec3ToJSON(b *testing.B) { } for _, ts := range encodeFuncs { b.Run(ts.name, func(b *testing.B) { + stop := func() { b.StopTimer() } + start := func() { b.StartTimer() } for i := 0; i < b.N; i++ { - if _, err := ts.f(vecs); err != nil { + if _, err := ts.f(start, stop, vecs); err != nil { b.Fatalf("Failed to marshal: %v", err) } }