|
|
@@ -1,109 +1,80 @@
|
|
|
-# go
|
|
|
-faster than DOM, more usable than SAX/StAX
|
|
|
+# json iterator (jsoniter)
|
|
|
|
|
|
-# string
|
|
|
+faster than DOM, more usable than SAX/StAX
|
|
|
|
|
|
-```
|
|
|
-func Benchmark_jsoniter_string(b *testing.B) {
|
|
|
- for n := 0; n < b.N; n++ {
|
|
|
- lexer := NewLexerWithArray([]byte(`"\ud83d\udc4a"`))
|
|
|
- lexer.LexString()
|
|
|
- }
|
|
|
-}
|
|
|
-```
|
|
|
+for performance numbers, see https://github.com/json-iterator/go-benchmark
|
|
|
|
|
|
-10000000 140 ns/op
|
|
|
+# DOM style api
|
|
|
|
|
|
```
|
|
|
-func Benchmark_json_string(b *testing.B) {
|
|
|
- for n := 0; n < b.N; n++ {
|
|
|
- result := ""
|
|
|
- json.Unmarshal([]byte(`"\ud83d\udc4a"`), &result)
|
|
|
- }
|
|
|
+type StructOfTag struct {
|
|
|
+ field1 string `json:"field-1"`
|
|
|
+ field2 string `json:"-"`
|
|
|
+ field3 int `json:",string"`
|
|
|
}
|
|
|
-````
|
|
|
-
|
|
|
-2000000 710 ns/op (5x slower)
|
|
|
-
|
|
|
-# int
|
|
|
|
|
|
-```
|
|
|
-func Benchmark_jsoniter_int(b *testing.B) {
|
|
|
- for n := 0; n < b.N; n++ {
|
|
|
- lexer := NewLexerWithArray([]byte(`-100`))
|
|
|
- lexer.LexInt64()
|
|
|
+func Test_reflect_struct_tag_field(t *testing.T) {
|
|
|
+ iter := ParseString(`{"field-1": "hello", "field2": "", "field3": "100"}`)
|
|
|
+ struct_ := StructOfTag{field2: "world"}
|
|
|
+ iter.Read(&struct_)
|
|
|
+ if struct_.field1 != "hello" {
|
|
|
+ fmt.Println(iter.Error)
|
|
|
+ t.Fatal(struct_.field1)
|
|
|
}
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-30000000 60.1 ns/op
|
|
|
-
|
|
|
-```
|
|
|
-func Benchmark_json_int(b *testing.B) {
|
|
|
- for n := 0; n < b.N; n++ {
|
|
|
- result := int64(0)
|
|
|
- json.Unmarshal([]byte(`-100`), &result)
|
|
|
+ if struct_.field2 != "world" {
|
|
|
+ fmt.Println(iter.Error)
|
|
|
+ t.Fatal(struct_.field2)
|
|
|
+ }
|
|
|
+ if struct_.field3 != 100 {
|
|
|
+ fmt.Println(iter.Error)
|
|
|
+ t.Fatal(struct_.field3)
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-3000000 505 ns/op (8x slower)
|
|
|
+# StAX style api
|
|
|
|
|
|
-# array
|
|
|
+Array
|
|
|
|
|
|
```
|
|
|
-func Benchmark_jsoniter_array(b *testing.B) {
|
|
|
- for n := 0; n < b.N; n++ {
|
|
|
- iter := ParseString(`[1,2,3]`)
|
|
|
- for iter.ReadArray() {
|
|
|
- iter.ReadUint64()
|
|
|
- }
|
|
|
- }
|
|
|
+iter := ParseString(`[1,2,3]`)
|
|
|
+for iter.ReadArray() {
|
|
|
+ iter.ReadUint64()
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-10000000 189 ns/op
|
|
|
+Object
|
|
|
|
|
|
```
|
|
|
-func Benchmark_json_array(b *testing.B) {
|
|
|
- for n := 0; n < b.N; n++ {
|
|
|
- result := []interface{}{}
|
|
|
- json.Unmarshal([]byte(`[1,2,3]`), &result)
|
|
|
- }
|
|
|
+type TestObj struct {
|
|
|
+ Field1 string
|
|
|
+ Field2 uint64
|
|
|
}
|
|
|
```
|
|
|
-1000000 1327 ns/op
|
|
|
-
|
|
|
-# object
|
|
|
|
|
|
```
|
|
|
-func Benchmark_jsoniter_object(b *testing.B) {
|
|
|
- for n := 0; n < b.N; n++ {
|
|
|
- iter := ParseString(`{"field1": "1", "field2": 2}`)
|
|
|
- obj := TestObj{}
|
|
|
- for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
|
|
|
- switch field {
|
|
|
- case "field1":
|
|
|
- obj.Field1 = iter.ReadString()
|
|
|
- case "field2":
|
|
|
- obj.Field2 = iter.ReadUint64()
|
|
|
- default:
|
|
|
- iter.ReportError("bind object", "unexpected field")
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+iter := ParseString(`{"field1": "1", "field2": 2}`)
|
|
|
+obj := TestObj{}
|
|
|
+for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
|
|
|
+ switch field {
|
|
|
+ case "field1":
|
|
|
+ obj.Field1 = iter.ReadString()
|
|
|
+ case "field2":
|
|
|
+ obj.Field2 = iter.ReadUint64()
|
|
|
+ default:
|
|
|
+ iter.ReportError("bind object", "unexpected field")
|
|
|
+ }
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-5000000 401 ns/op
|
|
|
+Skip
|
|
|
|
|
|
```
|
|
|
-func Benchmark_json_object(b *testing.B) {
|
|
|
- for n := 0; n < b.N; n++ {
|
|
|
- result := TestObj{}
|
|
|
- json.Unmarshal([]byte(`{"field1": "1", "field2": 2}`), &result)
|
|
|
- }
|
|
|
+iter := ParseString(`[ {"a" : [{"b": "c"}], "d": 102 }, "b"]`)
|
|
|
+iter.ReadArray()
|
|
|
+iter.Skip()
|
|
|
+iter.ReadArray()
|
|
|
+if iter.ReadString() != "b" {
|
|
|
+ t.FailNow()
|
|
|
}
|
|
|
-```
|
|
|
-
|
|
|
-1000000 1318 ns/op
|
|
|
+```
|