gitee.com/quant1x/pkg@v0.2.8/fastjson/README.md (about) 1 [![Build Status](https://travis-ci.org/valyala/fastjson.svg)](https://travis-ci.org/valyala/fastjson) 2 [![GoDoc](https://godoc.org/github.com/valyala/fastjson?status.svg)](http://godoc.org/github.com/valyala/fastjson) 3 [![Go Report](https://goreportcard.com/badge/github.com/valyala/fastjson)](https://goreportcard.com/report/github.com/valyala/fastjson) 4 [![codecov](https://codecov.io/gh/valyala/fastjson/branch/master/graph/badge.svg)](https://codecov.io/gh/valyala/fastjson) 5 6 # fastjson - fast JSON parser and validator for Go 7 8 9 ## Features 10 11 * Fast. As usual, up to 15x faster than the standard [encoding/json](https://golang.org/pkg/encoding/json/). 12 See [benchmarks](#benchmarks). 13 * Parses arbitrary JSON without schema, reflection, struct magic and code generation 14 contrary to [easyjson](https://github.com/mailru/easyjson). 15 * Provides simple [API](http://godoc.org/github.com/valyala/fastjson). 16 * Outperforms [jsonparser](https://github.com/buger/jsonparser) and [gjson](https://github.com/tidwall/gjson) 17 when accessing multiple unrelated fields, since `fastjson` parses the input JSON only once. 18 * Validates the parsed JSON unlike [jsonparser](https://github.com/buger/jsonparser) 19 and [gjson](https://github.com/tidwall/gjson). 20 * May quickly extract a part of the original JSON with `Value.Get(...).MarshalTo` and modify it 21 with [Del](https://godoc.org/github.com/valyala/fastjson#Value.Del) 22 and [Set](https://godoc.org/github.com/valyala/fastjson#Value.Set) functions. 23 * May parse array containing values with distinct types (aka non-homogenous types). 24 For instance, `fastjson` easily parses the following JSON array `[123, "foo", [456], {"k": "v"}, null]`. 25 * `fastjson` preserves the original order of object items when calling 26 [Object.Visit](https://godoc.org/github.com/valyala/fastjson#Object.Visit). 27 28 29 ## Known limitations 30 31 * Requies extra care to work with - references to certain objects recursively 32 returned by [Parser](https://godoc.org/github.com/valyala/fastjson#Parser) 33 must be released before the next call to [Parse](https://godoc.org/github.com/valyala/fastjson#Parser.Parse). 34 Otherwise the program may work improperly. The same applies to objects returned 35 by [Arena](https://godoc.org/github.com/valyala/fastjson#Arena). 36 Adhere recommendations from [docs](https://godoc.org/github.com/valyala/fastjson). 37 * Cannot parse JSON from `io.Reader`. There is [Scanner](https://godoc.org/github.com/valyala/fastjson#Scanner) 38 for parsing stream of JSON values from a string. 39 40 41 ## Usage 42 43 One-liner accessing a single field: 44 ```go 45 s := []byte(`{"foo": [123, "bar"]}`) 46 fmt.Printf("foo.0=%d\n", fastjson.GetInt(s, "foo", "0")) 47 48 // Output: 49 // foo.0=123 50 ``` 51 52 Accessing multiple fields with error handling: 53 ```go 54 var p fastjson.Parser 55 v, err := p.Parse(`{ 56 "str": "bar", 57 "int": 123, 58 "float": 1.23, 59 "bool": true, 60 "arr": [1, "foo", {}] 61 }`) 62 if err != nil { 63 log.Fatal(err) 64 } 65 fmt.Printf("foo=%s\n", v.GetStringBytes("str")) 66 fmt.Printf("int=%d\n", v.GetInt("int")) 67 fmt.Printf("float=%f\n", v.GetFloat64("float")) 68 fmt.Printf("bool=%v\n", v.GetBool("bool")) 69 fmt.Printf("arr.1=%s\n", v.GetStringBytes("arr", "1")) 70 71 // Output: 72 // foo=bar 73 // int=123 74 // float=1.230000 75 // bool=true 76 // arr.1=foo 77 ``` 78 79 See also [examples](https://godoc.org/github.com/valyala/fastjson#pkg-examples). 80 81 82 ## Security 83 84 * `fastjson` shouldn't crash or panic when parsing input strings specially crafted 85 by an attacker. It must return error on invalid input JSON. 86 * `fastjson` requires up to `sizeof(Value) * len(inputJSON)` bytes of memory 87 for parsing `inputJSON` string. Limit the maximum size of the `inputJSON` 88 before parsing it in order to limit the maximum memory usage. 89 90 91 ## Performance optimization tips 92 93 * Re-use [Parser](https://godoc.org/github.com/valyala/fastjson#Parser) 94 and [Scanner](https://godoc.org/github.com/valyala/fastjson#Scanner) 95 for parsing many JSONs. This reduces memory allocations overhead. 96 [ParserPool](https://godoc.org/github.com/valyala/fastjson#ParserPool) may be useful in this case. 97 * Prefer calling `Value.Get*` on the value returned from [Parser](https://godoc.org/github.com/valyala/fastjson#Parser) 98 instead of calling `Get*` one-liners when multiple fields 99 must be obtained from JSON, since each `Get*` one-liner re-parses 100 the input JSON again. 101 * Prefer calling once [Value.Get](https://godoc.org/github.com/valyala/fastjson#Value.Get) 102 for common prefix paths and then calling `Value.Get*` on the returned value 103 for distinct suffix paths. 104 * Prefer iterating over array returned from [Value.GetArray](https://godoc.org/github.com/valyala/fastjson#Object.Visit) 105 with a range loop instead of calling `Value.Get*` for each array item. 106 107 ## Fuzzing 108 Install [go-fuzz](https://github.com/dvyukov/go-fuzz) & optionally the go-fuzz-corpus. 109 110 ```bash 111 go get -u github.com/dvyukov/go-fuzz/go-fuzz github.com/dvyukov/go-fuzz/go-fuzz-build 112 ``` 113 114 Build using `go-fuzz-build` and run `go-fuzz` with an optional corpus. 115 116 ```bash 117 mkdir -p workdir/corpus 118 cp $GOPATH/src/github.com/dvyukov/go-fuzz-corpus/json/corpus/* workdir/corpus 119 go-fuzz-build github.com/valyala/fastjson 120 go-fuzz -bin=fastjson-fuzz.zip -workdir=workdir 121 ``` 122 123 ## Benchmarks 124 125 Go 1.12 has been used for benchmarking. 126 127 Legend: 128 129 * `small` - parse [small.json](testdata/small.json) (190 bytes). 130 * `medium` - parse [medium.json](testdata/medium.json) (2.3KB). 131 * `large` - parse [large.json](testdata/large.json) (28KB). 132 * `canada` - parse [canada.json](testdata/canada.json) (2.2MB). 133 * `citm` - parse [citm_catalog.json](testdata/citm_catalog.json) (1.7MB). 134 * `twitter` - parse [twitter.json](testdata/twitter.json) (617KB). 135 136 * `stdjson-map` - parse into a `map[string]interface{}` using `encoding/json`. 137 * `stdjson-struct` - parse into a struct containing 138 a subset of fields of the parsed JSON, using `encoding/json`. 139 * `stdjson-empty-struct` - parse into an empty struct using `encoding/json`. 140 This is the fastest possible solution for `encoding/json`, may be used 141 for json validation. See also benchmark results for json validation. 142 * `fastjson` - parse using `fastjson` without fields access. 143 * `fastjson-get` - parse using `fastjson` with fields access similar to `stdjson-struct`. 144 145 ``` 146 $ GOMAXPROCS=1 go test github.com/valyala/fastjson -bench='Parse$' 147 goos: linux 148 goarch: amd64 149 pkg: github.com/valyala/fastjson 150 BenchmarkParse/small/stdjson-map 200000 7305 ns/op 26.01 MB/s 960 B/op 51 allocs/op 151 BenchmarkParse/small/stdjson-struct 500000 3431 ns/op 55.37 MB/s 224 B/op 4 allocs/op 152 BenchmarkParse/small/stdjson-empty-struct 500000 2273 ns/op 83.58 MB/s 168 B/op 2 allocs/op 153 BenchmarkParse/small/fastjson 5000000 347 ns/op 547.53 MB/s 0 B/op 0 allocs/op 154 BenchmarkParse/small/fastjson-get 2000000 620 ns/op 306.39 MB/s 0 B/op 0 allocs/op 155 BenchmarkParse/medium/stdjson-map 30000 40672 ns/op 57.26 MB/s 10196 B/op 208 allocs/op 156 BenchmarkParse/medium/stdjson-struct 30000 47792 ns/op 48.73 MB/s 9174 B/op 258 allocs/op 157 BenchmarkParse/medium/stdjson-empty-struct 100000 22096 ns/op 105.40 MB/s 280 B/op 5 allocs/op 158 BenchmarkParse/medium/fastjson 500000 3025 ns/op 769.90 MB/s 0 B/op 0 allocs/op 159 BenchmarkParse/medium/fastjson-get 500000 3211 ns/op 725.20 MB/s 0 B/op 0 allocs/op 160 BenchmarkParse/large/stdjson-map 2000 614079 ns/op 45.79 MB/s 210734 B/op 2785 allocs/op 161 BenchmarkParse/large/stdjson-struct 5000 298554 ns/op 94.18 MB/s 15616 B/op 353 allocs/op 162 BenchmarkParse/large/stdjson-empty-struct 5000 268577 ns/op 104.69 MB/s 280 B/op 5 allocs/op 163 BenchmarkParse/large/fastjson 50000 35210 ns/op 798.56 MB/s 5 B/op 0 allocs/op 164 BenchmarkParse/large/fastjson-get 50000 35171 ns/op 799.46 MB/s 5 B/op 0 allocs/op 165 BenchmarkParse/canada/stdjson-map 20 68147307 ns/op 33.03 MB/s 12260502 B/op 392539 allocs/op 166 BenchmarkParse/canada/stdjson-struct 20 68044518 ns/op 33.08 MB/s 12260123 B/op 392534 allocs/op 167 BenchmarkParse/canada/stdjson-empty-struct 100 17709250 ns/op 127.11 MB/s 280 B/op 5 allocs/op 168 BenchmarkParse/canada/fastjson 300 4182404 ns/op 538.22 MB/s 254902 B/op 381 allocs/op 169 BenchmarkParse/canada/fastjson-get 300 4274744 ns/op 526.60 MB/s 254902 B/op 381 allocs/op 170 BenchmarkParse/citm/stdjson-map 50 27772612 ns/op 62.19 MB/s 5214163 B/op 95402 allocs/op 171 BenchmarkParse/citm/stdjson-struct 100 14936191 ns/op 115.64 MB/s 1989 B/op 75 allocs/op 172 BenchmarkParse/citm/stdjson-empty-struct 100 14946034 ns/op 115.56 MB/s 280 B/op 5 allocs/op 173 BenchmarkParse/citm/fastjson 1000 1879714 ns/op 918.87 MB/s 17628 B/op 30 allocs/op 174 BenchmarkParse/citm/fastjson-get 1000 1881598 ns/op 917.94 MB/s 17628 B/op 30 allocs/op 175 BenchmarkParse/twitter/stdjson-map 100 11289146 ns/op 55.94 MB/s 2187878 B/op 31266 allocs/op 176 BenchmarkParse/twitter/stdjson-struct 300 5779442 ns/op 109.27 MB/s 408 B/op 6 allocs/op 177 BenchmarkParse/twitter/stdjson-empty-struct 300 5738504 ns/op 110.05 MB/s 408 B/op 6 allocs/op 178 BenchmarkParse/twitter/fastjson 2000 774042 ns/op 815.86 MB/s 2541 B/op 2 allocs/op 179 BenchmarkParse/twitter/fastjson-get 2000 777833 ns/op 811.89 MB/s 2541 B/op 2 allocs/op 180 ``` 181 182 Benchmark results for json validation: 183 184 ``` 185 $ GOMAXPROCS=1 go test github.com/valyala/fastjson -bench='Validate$' 186 goos: linux 187 goarch: amd64 188 pkg: github.com/valyala/fastjson 189 BenchmarkValidate/small/stdjson 2000000 955 ns/op 198.83 MB/s 72 B/op 2 allocs/op 190 BenchmarkValidate/small/fastjson 5000000 384 ns/op 493.60 MB/s 0 B/op 0 allocs/op 191 BenchmarkValidate/medium/stdjson 200000 10799 ns/op 215.66 MB/s 184 B/op 5 allocs/op 192 BenchmarkValidate/medium/fastjson 300000 3809 ns/op 611.30 MB/s 0 B/op 0 allocs/op 193 BenchmarkValidate/large/stdjson 10000 133064 ns/op 211.31 MB/s 184 B/op 5 allocs/op 194 BenchmarkValidate/large/fastjson 30000 45268 ns/op 621.14 MB/s 0 B/op 0 allocs/op 195 BenchmarkValidate/canada/stdjson 200 8470904 ns/op 265.74 MB/s 184 B/op 5 allocs/op 196 BenchmarkValidate/canada/fastjson 500 2973377 ns/op 757.07 MB/s 0 B/op 0 allocs/op 197 BenchmarkValidate/citm/stdjson 200 7273172 ns/op 237.48 MB/s 184 B/op 5 allocs/op 198 BenchmarkValidate/citm/fastjson 1000 1684430 ns/op 1025.39 MB/s 0 B/op 0 allocs/op 199 BenchmarkValidate/twitter/stdjson 500 2849439 ns/op 221.63 MB/s 312 B/op 6 allocs/op 200 BenchmarkValidate/twitter/fastjson 2000 1036796 ns/op 609.10 MB/s 0 B/op 0 allocs/op 201 ``` 202 203 ## FAQ 204 205 * Q: _There are a ton of other high-perf packages for JSON parsing in Go. Why creating yet another package?_ 206 A: Because other packages require either rigid JSON schema via struct magic 207 and code generation or perform poorly when multiple unrelated fields 208 must be obtained from the parsed JSON. 209 Additionally, `fastjson` provides nicer [API](http://godoc.org/github.com/valyala/fastjson). 210 211 * Q: _What is the main purpose for `fastjson`?_ 212 A: High-perf JSON parsing 213 for [RTB](https://www.iab.com/wp-content/uploads/2015/05/OpenRTB_API_Specification_Version_2_3_1.pdf) 214 and other [JSON-RPC](https://en.wikipedia.org/wiki/JSON-RPC) services. 215 216 * Q: _Why fastjson doesn't provide fast marshaling (serialization)?_ 217 A: Actually it provides some sort of marshaling - 218 see [Value.MarshalTo](https://godoc.org/github.com/valyala/fastjson#Value.MarshalTo). 219 But I'd recommend using [quicktemplate](https://github.com/valyala/quicktemplate#use-cases) 220 for high-performance JSON marshaling :) 221 222 * Q: _`fastjson` crashes my program!_ 223 A: There is high probability of improper use. 224 * Make sure you don't hold references to objects recursively returned by `Parser` / `Scanner` 225 beyond the next `Parser.Parse` / `Scanner.Next` call 226 if such restriction is mentioned in [docs](https://github.com/valyala/fastjson/issues/new). 227 * Make sure you don't access `fastjson` objects from concurrently running goroutines 228 if such restriction is mentioned in [docs](https://github.com/valyala/fastjson/issues/new). 229 * Build and run your program with [-race](https://golang.org/doc/articles/race_detector.html) flag. 230 Make sure the race detector detects zero races. 231 * If your program continue crashing after fixing issues mentioned 232 above, [file a bug](https://github.com/valyala/fastjson/issues/new).