updated benchmarks, added features list

This commit is contained in:
Josh Baker 2017-04-14 11:13:32 -07:00
parent a8ccb8767a
commit 6e0babc7e8
2 changed files with 120 additions and 18 deletions

View File

@ -3,15 +3,14 @@
src="logo.png"
width="240" height="78" border="0" alt="GJSON">
<br>
<a href="https://travis-ci.org/tidwall/gjson"><img src="https://img.shields.io/travis/tidwall/gjson.svg?style=flat-square" alt="Build Status"></a><!--
<a href="http://gocover.io/github.com/tidwall/gjson"><img src="https://img.shields.io/badge/coverage-97%25-brightgreen.svg?style=flat-square" alt="Code Coverage"></a>
-->
<a href="https://travis-ci.org/tidwall/gjson"><img src="https://img.shields.io/travis/tidwall/gjson.svg?style=flat-square" alt="Build Status"></a>
<a href="https://godoc.org/github.com/tidwall/gjson"><img src="https://img.shields.io/badge/api-reference-blue.svg?style=flat-square" alt="GoDoc"></a>
</p>
<p align="center">get a json value quickly</a></p>
GJSON is a Go package that provides a [fast](#performance) and [simple](#get-a-value) way to get values from a json document with one line of code.
GJSON is a Go package that provides a [fast](#performance) and [simple](#get-a-value) way to get values from a json document.
It has features such as [one line retrieval](#get-a-value), [dot notation paths](#path-syntax), [iteration](#iterate-through-an-object-or-array), and [map unmarshalling](#unmarshal-to-a-map).
Getting Started
===============
@ -283,26 +282,28 @@ The return value is a `[]Result`, which will always contain exactly the same num
Benchmarks of GJSON alongside [encoding/json](https://golang.org/pkg/encoding/json/),
[ffjson](https://github.com/pquerna/ffjson),
[EasyJSON](https://github.com/mailru/easyjson),
and [jsonparser](https://github.com/buger/jsonparser)
[jsonparser](https://github.com/buger/jsonparser),
and [json-iterator](https://github.com/json-iterator/go)
```
BenchmarkGJSONGet-8 15000000 333 ns/op 0 B/op 0 allocs/op
BenchmarkGJSONUnmarshalMap-8 900000 4188 ns/op 1920 B/op 26 allocs/op
BenchmarkJSONUnmarshalMap-8 600000 8908 ns/op 3048 B/op 69 allocs/op
BenchmarkJSONUnmarshalStruct-8 600000 9026 ns/op 1832 B/op 69 allocs/op
BenchmarkJSONDecoder-8 300000 14339 ns/op 4224 B/op 184 allocs/op
BenchmarkFFJSONLexer-8 1500000 3156 ns/op 896 B/op 8 allocs/op
BenchmarkEasyJSONLexer-8 3000000 938 ns/op 613 B/op 6 allocs/op
BenchmarkJSONParserGet-8 3000000 442 ns/op 21 B/op 0 allocs/op
BenchmarkGJSONGet-8 3000000 372 ns/op 0 B/op 0 allocs/op
BenchmarkGJSONUnmarshalMap-8 900000 4154 ns/op 1920 B/op 26 allocs/op
BenchmarkJSONUnmarshalMap-8 600000 9019 ns/op 3048 B/op 69 allocs/op
BenchmarkJSONUnmarshalStruct-8 600000 9268 ns/op 1832 B/op 69 allocs/op
BenchmarkJSONDecoder-8 300000 14120 ns/op 4224 B/op 184 allocs/op
BenchmarkFFJSONLexer-8 1500000 3111 ns/op 896 B/op 8 allocs/op
BenchmarkEasyJSONLexer-8 3000000 887 ns/op 613 B/op 6 allocs/op
BenchmarkJSONParserGet-8 3000000 499 ns/op 21 B/op 0 allocs/op
BenchmarkJSONIterator-8 3000000 812 ns/op 544 B/op 9 allocs/op
```
Benchmarks for the `GetMany` function:
```
BenchmarkGJSONGetMany4Paths-8 4000000 319 ns/op 112 B/op 0 allocs/op
BenchmarkGJSONGetMany8Paths-8 8000000 218 ns/op 56 B/op 0 allocs/op
BenchmarkGJSONGetMany16Paths-8 16000000 160 ns/op 56 B/op 0 allocs/op
BenchmarkGJSONGetMany32Paths-8 32000000 130 ns/op 64 B/op 0 allocs/op
BenchmarkGJSONGetMany4Paths-8 4000000 303 ns/op 112 B/op 0 allocs/op
BenchmarkGJSONGetMany8Paths-8 8000000 208 ns/op 56 B/op 0 allocs/op
BenchmarkGJSONGetMany16Paths-8 16000000 156 ns/op 56 B/op 0 allocs/op
BenchmarkGJSONGetMany32Paths-8 32000000 127 ns/op 64 B/op 0 allocs/op
BenchmarkGJSONGetMany64Paths-8 64000000 117 ns/op 64 B/op 0 allocs/op
BenchmarkGJSONGetMany128Paths-8 128000000 109 ns/op 64 B/op 0 allocs/op
```
@ -360,7 +361,7 @@ widget.text.data
widget.text.size
```
*These benchmarks were run on a MacBook Pro 15" 2.8 GHz Intel Core i7 using Go 1.7.*
*These benchmarks were run on a MacBook Pro 15" 2.8 GHz Intel Core i7 using Go 1.8.*
## Contact
Josh Baker [@tidwall](http://twitter.com/tidwall)

View File

@ -12,6 +12,7 @@ import (
"time"
"github.com/buger/jsonparser"
jsoniter "github.com/json-iterator/go"
"github.com/mailru/easyjson/jlexer"
fflib "github.com/pquerna/ffjson/fflib/v1"
)
@ -1163,6 +1164,106 @@ func BenchmarkJSONParserGet(t *testing.B) {
}
t.N *= len(benchPaths) // because we are running against 3 paths
}
func jsoniterWindowName(t *testing.B, iter *jsoniter.Iterator) {
var v string
for {
key := iter.ReadObject()
if key != "window" {
iter.Skip()
continue
}
for {
key := iter.ReadObject()
if key != "name" {
iter.Skip()
continue
}
v = iter.ReadString()
break
}
break
}
if v == "" {
t.Fatal("did not find the value")
}
}
func jsoniterTextOnMouseUp(t *testing.B, iter *jsoniter.Iterator) {
var v string
for {
key := iter.ReadObject()
if key != "text" {
iter.Skip()
continue
}
for {
key := iter.ReadObject()
if key != "onMouseUp" {
iter.Skip()
continue
}
v = iter.ReadString()
break
}
break
}
if v == "" {
t.Fatal("did not find the value")
}
}
func jsoniterImageOffset(t *testing.B, iter *jsoniter.Iterator) {
var v int
for {
key := iter.ReadObject()
if key != "image" {
iter.Skip()
continue
}
for {
key := iter.ReadObject()
if key != "hOffset" {
iter.Skip()
continue
}
v = iter.ReadInt()
break
}
break
}
if v == 0 {
t.Fatal("did not find the value")
}
}
func jsoniterWidget(t *testing.B, iter *jsoniter.Iterator, j int) {
for {
key := iter.ReadObject()
if key != "widget" {
iter.Skip()
continue
}
switch benchPaths[j] {
case "widget.window.name":
jsoniterWindowName(t, iter)
case "widget.image.hOffset":
jsoniterImageOffset(t, iter)
case "widget.text.onMouseUp":
jsoniterTextOnMouseUp(t, iter)
}
break
}
}
func BenchmarkJSONIterator(t *testing.B) {
t.ReportAllocs()
t.ResetTimer()
for i := 0; i < t.N; i++ {
for j := 0; j < len(benchPaths); j++ {
iter := jsoniter.ParseString(exampleJSON)
jsoniterWidget(t, iter, j)
}
}
t.N *= len(benchPaths) // because we are running against 3 paths
}
var massiveJSON = func() string {
var buf bytes.Buffer