Skip to content

Commit 74ab6d7

Browse files
authored
Merge pull request #60 from AsaiYusuke/fix/add-precheck
add test validation
2 parents 7349ee3 + bbcc141 commit 74ab6d7

12 files changed

Lines changed: 249 additions & 54 deletions

README.md

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,16 @@ goos: linux
4646
goarch: amd64
4747
pkg: github.com/AsaiYusuke/jsonpath_benchmark
4848
cpu: AMD EPYC 7763 64-Core Processor
49-
Benchmark1_AsaiYusuke_JSONPath_reuseBuffer-4 19614597 61.09 ns/op 0 B/op 0 allocs/op
50-
Benchmark1_oliveagle_JsonPath-4 16205835 74.08 ns/op 0 B/op 0 allocs/op
51-
Benchmark1_AsaiYusuke_JSONPath-4 12229542 97.86 ns/op 16 B/op 1 allocs/op
52-
Benchmark1_ohler55_OjG_jp-4 3423679 377.3 ns/op 1168 B/op 2 allocs/op
53-
Benchmark1_PaesslerAG_JSONPath-4 2974052 402.1 ns/op 208 B/op 7 allocs/op
54-
Benchmark1_vmware_labs_YAML_JSONPath-4 1330934 901.1 ns/op 464 B/op 28 allocs/op
55-
Benchmark1_bhmj_JSON_Slice-4 935232 1264 ns/op 24 B/op 1 allocs/op
56-
Benchmark1_Spyzhov_Abstract_JSON-4 818025 1379 ns/op 472 B/op 25 allocs/op
49+
Benchmark1_AsaiYusuke_JSONPath_reuseBuffer-4 18992085 62.50 ns/op 0 B/op 0 allocs/op
50+
Benchmark1_oliveagle_JsonPath-4 16875874 70.56 ns/op 0 B/op 0 allocs/op
51+
Benchmark1_AsaiYusuke_JSONPath-4 11419996 103.9 ns/op 16 B/op 1 allocs/op
52+
Benchmark1_ohler55_OjG_jp-4 3395434 350.9 ns/op 1168 B/op 2 allocs/op
53+
Benchmark1_PaesslerAG_JSONPath-4 2958105 399.7 ns/op 208 B/op 7 allocs/op
54+
Benchmark1_vmware_labs_YAML_JSONPath-4 1323622 907.0 ns/op 464 B/op 28 allocs/op
55+
Benchmark1_bhmj_JSON_Slice-4 929371 1286 ns/op 24 B/op 1 allocs/op
56+
Benchmark1_Spyzhov_Abstract_JSON-4 863251 1431 ns/op 472 B/op 25 allocs/op
5757
PASS
58-
ok github.com/AsaiYusuke/jsonpath_benchmark 9.600s
58+
ok github.com/AsaiYusuke/jsonpath_benchmark 9.578s
5959

6060
```
6161

@@ -77,14 +77,13 @@ goos: linux
7777
goarch: amd64
7878
pkg: github.com/AsaiYusuke/jsonpath_benchmark
7979
cpu: AMD EPYC 7763 64-Core Processor
80-
Benchmark2_AsaiYusuke_JSONPath_reuseBuffer-4 1000000 1132 ns/op 80 B/op 2 allocs/op
81-
Benchmark2_AsaiYusuke_JSONPath-4 1000000 1172 ns/op 96 B/op 3 allocs/op
82-
Benchmark2_ohler55_OjG_jp-4 319904 3652 ns/op 6200 B/op 37 allocs/op
83-
Benchmark2_vmware_labs_YAML_JSONPath-4 287280 4101 ns/op 4416 B/op 136 allocs/op
84-
Benchmark2_bhmj_JSON_Slice-4 72646 16051 ns/op 1784 B/op 38 allocs/op
85-
Benchmark2_Spyzhov_Abstract_JSON-4 78049 15659 ns/op 5480 B/op 223 allocs/op
80+
Benchmark2_AsaiYusuke_JSONPath_reuseBuffer-4 1000000 1130 ns/op 80 B/op 2 allocs/op
81+
Benchmark2_AsaiYusuke_JSONPath-4 1000000 1169 ns/op 96 B/op 3 allocs/op
82+
Benchmark2_ohler55_OjG_jp-4 312778 3794 ns/op 6200 B/op 37 allocs/op
83+
Benchmark2_bhmj_JSON_Slice-4 75607 15887 ns/op 1784 B/op 38 allocs/op
84+
Benchmark2_Spyzhov_Abstract_JSON-4 77376 16420 ns/op 5480 B/op 223 allocs/op
8685
PASS
87-
ok github.com/AsaiYusuke/jsonpath_benchmark 7.046s
86+
ok github.com/AsaiYusuke/jsonpath_benchmark 5.965s
8887

8988
```
9089

benchmark_recursiveDescentWithFilter_test.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,42 @@ import (
55
)
66

77
var jsonPath_recursiveDescentWithFilter string = `$..book[?(@.price > $.store.bicycle.price)]`
8+
var expect_recursiveDescentWithFilter = &BenchExpect{Values: []any{map[string]any{
9+
"category": "fiction",
10+
"author": "J. R. R. Tolkien",
11+
"title": "The Lord of the Rings",
12+
"isbn": "0-395-19395-8",
13+
"price": 22.99,
14+
}}}
815

916
func Benchmark2_AsaiYusuke_JSONPath_reuseBuffer(b *testing.B) {
10-
Execute_AsaiYusuke_JSONPath_reuseBuffer(b, srcJSON, jsonPath_recursiveDescentWithFilter)
17+
Execute_AsaiYusuke_JSONPath_reuseBuffer(b, srcJSON, jsonPath_recursiveDescentWithFilter, expect_recursiveDescentWithFilter)
1118
}
1219

1320
func Benchmark2_AsaiYusuke_JSONPath(b *testing.B) {
14-
Execute_AsaiYusuke_JSONPath(b, srcJSON, jsonPath_recursiveDescentWithFilter)
21+
Execute_AsaiYusuke_JSONPath(b, srcJSON, jsonPath_recursiveDescentWithFilter, expect_recursiveDescentWithFilter)
1522
}
1623

1724
func Benchmark2_ohler55_OjG_jp(b *testing.B) {
18-
Execute_ohler55_OjG_jp(b, srcJSON, jsonPath_recursiveDescentWithFilter)
19-
}
20-
21-
func Benchmark2_vmware_labs_YAML_JSONPath(b *testing.B) {
22-
Execute_vmware_labs_YAML_JSONPath(b, srcJSON, jsonPath_recursiveDescentWithFilter)
25+
Execute_ohler55_OjG_jp(b, srcJSON, jsonPath_recursiveDescentWithFilter, expect_recursiveDescentWithFilter)
2326
}
2427

2528
func Benchmark2_bhmj_JSON_Slice(b *testing.B) {
26-
Execute_bhmj_JSON_Slice(b, srcJSON, jsonPath_recursiveDescentWithFilter)
29+
Execute_bhmj_JSON_Slice(b, srcJSON, jsonPath_recursiveDescentWithFilter, expect_recursiveDescentWithFilter)
2730
}
2831

2932
func Benchmark2_Spyzhov_Abstract_JSON(b *testing.B) {
30-
Execute_Spyzhov_Abstract_JSON(b, srcJSON, jsonPath_recursiveDescentWithFilter)
33+
Execute_Spyzhov_Abstract_JSON(b, srcJSON, jsonPath_recursiveDescentWithFilter, expect_recursiveDescentWithFilter)
34+
}
35+
36+
func Benchmark2_vmware_labs_YAML_JSONPath(b *testing.B) {
37+
Execute_vmware_labs_YAML_JSONPath(b, srcJSON, jsonPath_recursiveDescentWithFilter, expect_recursiveDescentWithFilter)
3138
}
3239

3340
func Benchmark2_oliveagle_JsonPath(b *testing.B) {
34-
Execute_oliveagle_JsonPath(b, srcJSON, jsonPath_recursiveDescentWithFilter)
41+
Execute_oliveagle_JsonPath(b, srcJSON, jsonPath_recursiveDescentWithFilter, expect_recursiveDescentWithFilter)
3542
}
3643

3744
func Benchmark2_PaesslerAG_JSONPath(b *testing.B) {
38-
Execute_PaesslerAG_JSONPath(b, srcJSON, jsonPath_recursiveDescentWithFilter)
45+
Execute_PaesslerAG_JSONPath(b, srcJSON, jsonPath_recursiveDescentWithFilter, expect_recursiveDescentWithFilter)
3946
}

benchmark_threeLevelsWithIndex_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,36 @@ import (
55
)
66

77
var jsonPath_threeLevelsWithIndex string = `$.store.book[0].price`
8+
var expect_threeLevelsWithIndex = &BenchExpect{Values: []any{8.95}}
89

910
func Benchmark1_AsaiYusuke_JSONPath_reuseBuffer(b *testing.B) {
10-
Execute_AsaiYusuke_JSONPath_reuseBuffer(b, srcJSON, jsonPath_threeLevelsWithIndex)
11+
Execute_AsaiYusuke_JSONPath_reuseBuffer(b, srcJSON, jsonPath_threeLevelsWithIndex, expect_threeLevelsWithIndex)
1112
}
1213

1314
func Benchmark1_oliveagle_JsonPath(b *testing.B) {
14-
Execute_oliveagle_JsonPath(b, srcJSON, jsonPath_threeLevelsWithIndex)
15+
Execute_oliveagle_JsonPath(b, srcJSON, jsonPath_threeLevelsWithIndex, expect_threeLevelsWithIndex)
1516
}
1617

1718
func Benchmark1_AsaiYusuke_JSONPath(b *testing.B) {
18-
Execute_AsaiYusuke_JSONPath(b, srcJSON, jsonPath_threeLevelsWithIndex)
19+
Execute_AsaiYusuke_JSONPath(b, srcJSON, jsonPath_threeLevelsWithIndex, expect_threeLevelsWithIndex)
1920
}
2021

2122
func Benchmark1_ohler55_OjG_jp(b *testing.B) {
22-
Execute_ohler55_OjG_jp(b, srcJSON, jsonPath_threeLevelsWithIndex)
23+
Execute_ohler55_OjG_jp(b, srcJSON, jsonPath_threeLevelsWithIndex, expect_threeLevelsWithIndex)
2324
}
2425

2526
func Benchmark1_PaesslerAG_JSONPath(b *testing.B) {
26-
Execute_PaesslerAG_JSONPath(b, srcJSON, jsonPath_threeLevelsWithIndex)
27+
Execute_PaesslerAG_JSONPath(b, srcJSON, jsonPath_threeLevelsWithIndex, expect_threeLevelsWithIndex)
2728
}
2829

2930
func Benchmark1_vmware_labs_YAML_JSONPath(b *testing.B) {
30-
Execute_vmware_labs_YAML_JSONPath(b, srcJSON, jsonPath_threeLevelsWithIndex)
31+
Execute_vmware_labs_YAML_JSONPath(b, srcJSON, jsonPath_threeLevelsWithIndex, expect_threeLevelsWithIndex)
3132
}
3233

3334
func Benchmark1_bhmj_JSON_Slice(b *testing.B) {
34-
Execute_bhmj_JSON_Slice(b, srcJSON, jsonPath_threeLevelsWithIndex)
35+
Execute_bhmj_JSON_Slice(b, srcJSON, jsonPath_threeLevelsWithIndex, expect_threeLevelsWithIndex)
3536
}
3637

3738
func Benchmark1_Spyzhov_Abstract_JSON(b *testing.B) {
38-
Execute_Spyzhov_Abstract_JSON(b, srcJSON, jsonPath_threeLevelsWithIndex)
39+
Execute_Spyzhov_Abstract_JSON(b, srcJSON, jsonPath_threeLevelsWithIndex, expect_threeLevelsWithIndex)
3940
}

exec_AsaiYusukeJSONPath.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import (
77
"github.com/AsaiYusuke/jsonpath/v2"
88
)
99

10-
func Execute_AsaiYusuke_JSONPath(b *testing.B, srcJSON string, jsonPath string) {
11-
b.Helper()
10+
func Execute_AsaiYusuke_JSONPath(b *testing.B, srcJSON string, jsonPath string, expect *BenchExpect) {
1211

1312
var src any
1413
if err := json.Unmarshal([]byte(srcJSON), &src); err != nil {
@@ -21,6 +20,19 @@ func Execute_AsaiYusuke_JSONPath(b *testing.B, srcJSON string, jsonPath string)
2120
b.Skip(err)
2221
return
2322
}
23+
result, err := parserFunc(src)
24+
if err != nil {
25+
b.Skip(err)
26+
return
27+
}
28+
if ok, reason := expect.validateSlice(result); !ok {
29+
if reason != "" {
30+
b.Skipf("precheck failed: %s", reason)
31+
} else {
32+
b.Skip("precheck failed")
33+
}
34+
return
35+
}
2436

2537
for b.Loop() {
2638
if _, err := parserFunc(src); err != nil {

exec_AsaiYusukeJSONPath_reuse.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import (
77
"github.com/AsaiYusuke/jsonpath/v2"
88
)
99

10-
func Execute_AsaiYusuke_JSONPath_reuseBuffer(b *testing.B, srcJSON string, jsonPath string) {
11-
b.Helper()
10+
func Execute_AsaiYusuke_JSONPath_reuseBuffer(b *testing.B, srcJSON string, jsonPath string, expect *BenchExpect) {
1211

1312
var src any
1413
if err := json.Unmarshal([]byte(srcJSON), &src); err != nil {
@@ -21,6 +20,19 @@ func Execute_AsaiYusuke_JSONPath_reuseBuffer(b *testing.B, srcJSON string, jsonP
2120
b.Skip(err)
2221
return
2322
}
23+
result, err := parserFunc(src)
24+
if err != nil {
25+
b.Skip(err)
26+
return
27+
}
28+
if ok, reason := expect.validateSlice(result); !ok {
29+
if reason != "" {
30+
b.Skipf("precheck failed: %s", reason)
31+
} else {
32+
b.Skip("precheck failed")
33+
}
34+
return
35+
}
2436

2537
buf := make([]any, 0, 256)
2638
args := []*[]any{&buf}

exec_BhmjJSONSlice.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,41 @@
11
package jsonpath_benchmark
22

33
import (
4+
"encoding/json"
45
"testing"
56

67
"github.com/bhmj/jsonslice"
78
)
89

9-
func Execute_bhmj_JSON_Slice(b *testing.B, srcJSON string, jsonPath string) {
10-
b.Helper()
10+
func Execute_bhmj_JSON_Slice(b *testing.B, srcJSON string, jsonPath string, expect *BenchExpect) {
1111

1212
var src = []byte(srcJSON)
13+
binaryResult, err := jsonslice.Get(src, jsonPath)
14+
if err != nil {
15+
b.Skip(err)
16+
return
17+
}
18+
19+
var value any
20+
if err := json.Unmarshal(binaryResult, &value); err != nil {
21+
b.Skip(err)
22+
return
23+
}
24+
25+
result, ok := value.([]any)
26+
if ok {
27+
result = result[0].([]any)
28+
} else {
29+
result = []any{value}
30+
}
31+
if ok, reason := expect.validateSlice(result); !ok {
32+
if reason != "" {
33+
b.Skipf("precheck failed: %s", reason)
34+
} else {
35+
b.Skip("precheck failed")
36+
}
37+
return
38+
}
1339

1440
for b.Loop() {
1541
if _, err := jsonslice.Get(src, jsonPath); err != nil {

exec_Ohler55Ojg.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import (
77
"github.com/ohler55/ojg/oj"
88
)
99

10-
func Execute_ohler55_OjG_jp(b *testing.B, srcJSON string, jsonPath string) {
11-
b.Helper()
10+
func Execute_ohler55_OjG_jp(b *testing.B, srcJSON string, jsonPath string, expect *BenchExpect) {
1211

1312
obj, err := oj.ParseString(srcJSON)
1413
if err != nil {
@@ -21,6 +20,15 @@ func Execute_ohler55_OjG_jp(b *testing.B, srcJSON string, jsonPath string) {
2120
b.Skip(err)
2221
return
2322
}
23+
result := x.Get(obj)
24+
if ok, reason := expect.validateSlice(result); !ok {
25+
if reason != "" {
26+
b.Skipf("precheck failed: %s", reason)
27+
} else {
28+
b.Skip("precheck failed")
29+
}
30+
return
31+
}
2432

2533
for b.Loop() {
2634
x.Get(obj)

exec_OliveagleJsonpath.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import (
77
"github.com/oliveagle/jsonpath"
88
)
99

10-
func Execute_oliveagle_JsonPath(b *testing.B, srcJSON string, jsonPath string) {
11-
b.Helper()
10+
func Execute_oliveagle_JsonPath(b *testing.B, srcJSON string, jsonPath string, expect *BenchExpect) {
1211

1312
var src any
1413
if err := json.Unmarshal([]byte(srcJSON), &src); err != nil {
@@ -21,6 +20,20 @@ func Execute_oliveagle_JsonPath(b *testing.B, srcJSON string, jsonPath string) {
2120
b.Skip(err)
2221
return
2322
}
23+
value, err := pat.Lookup(src)
24+
if err != nil {
25+
b.Skip(err)
26+
return
27+
}
28+
result := []any{value}
29+
if ok, reason := expect.validateSlice(result); !ok {
30+
if reason != "" {
31+
b.Skipf("precheck failed: %s", reason)
32+
} else {
33+
b.Skip("precheck failed")
34+
}
35+
return
36+
}
2437

2538
for b.Loop() {
2639
if _, err := pat.Lookup(src); err != nil {

exec_PaesslerAGJSONPath.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import (
88
"github.com/PaesslerAG/jsonpath"
99
)
1010

11-
func Execute_PaesslerAG_JSONPath(b *testing.B, srcJSON string, jsonPath string) {
12-
b.Helper()
11+
func Execute_PaesslerAG_JSONPath(b *testing.B, srcJSON string, jsonPath string, expect *BenchExpect) {
1312

1413
var src any
1514
if err := json.Unmarshal([]byte(srcJSON), &src); err != nil {
@@ -22,6 +21,20 @@ func Execute_PaesslerAG_JSONPath(b *testing.B, srcJSON string, jsonPath string)
2221
b.Skip(err)
2322
return
2423
}
24+
value, err := eval(context.Background(), src)
25+
if err != nil {
26+
b.Skip(err)
27+
return
28+
}
29+
result := []any{value}
30+
if ok, reason := expect.validateSlice(result); !ok {
31+
if reason != "" {
32+
b.Skipf("precheck failed: %s", reason)
33+
} else {
34+
b.Skip("precheck failed")
35+
}
36+
return
37+
}
2538

2639
for b.Loop() {
2740
if _, err := eval(context.Background(), src); err != nil {

exec_SpyzhovAjson.go

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,53 @@ import (
66
"github.com/spyzhov/ajson"
77
)
88

9-
func Execute_Spyzhov_Abstract_JSON(b *testing.B, srcJSON string, jsonPath string) {
10-
b.Helper()
9+
func Execute_Spyzhov_Abstract_JSON(b *testing.B, srcJSON string, jsonPath string, expect *BenchExpect) {
1110

1211
json := []byte(srcJSON)
1312

1413
root, _ := ajson.Unmarshal(json)
1514

15+
nodes, err := root.JSONPath(jsonPath)
16+
if err != nil {
17+
b.Skip(err)
18+
return
19+
}
20+
21+
result := make([]any, 0, len(nodes))
22+
for _, n := range nodes {
23+
switch n.Type() {
24+
case ajson.Numeric:
25+
if value, err := n.GetNumeric(); err == nil {
26+
result = append(result, value)
27+
}
28+
case ajson.Object:
29+
if value, err := n.GetObject(); err == nil {
30+
m := map[string]any{}
31+
for key, child := range value {
32+
switch child.Type() {
33+
case ajson.String:
34+
if s, err := child.GetString(); err == nil {
35+
m[key] = s
36+
}
37+
case ajson.Numeric:
38+
if n, err := child.GetNumeric(); err == nil {
39+
m[key] = n
40+
}
41+
}
42+
}
43+
result = append(result, m)
44+
}
45+
}
46+
}
47+
if ok, reason := expect.validateSlice(result); !ok {
48+
if reason != "" {
49+
b.Skipf("precheck failed: %s", reason)
50+
} else {
51+
b.Skip("precheck failed")
52+
}
53+
return
54+
}
55+
1656
for b.Loop() {
1757
if _, err := root.JSONPath(jsonPath); err != nil {
1858
b.Skip(err)

0 commit comments

Comments
 (0)