├── main.go ├── README.md └── bench_test.go /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "flag" 6 | "io/ioutil" 7 | "log" 8 | 9 | jmespath "github.com/jmespath/go-jmespath" 10 | ) 11 | 12 | func main() { 13 | var ( 14 | input = flag.String("file", "data.json", "file containing JSON") 15 | expr = flag.String("expr", "", "JMESPath expression") 16 | ) 17 | flag.Parse() 18 | if input == nil { 19 | log.Fatal("--file flag missing") 20 | } 21 | if expr == nil { 22 | log.Fatal("--expr flag missing") 23 | } 24 | data, err := ioutil.ReadFile(*input) 25 | if err != nil { 26 | log.Fatal(err) 27 | } 28 | out, err := Apply(*expr, data) 29 | if err != nil { 30 | log.Fatal(err) 31 | } 32 | log.Printf("%v", out) 33 | } 34 | 35 | func Apply(expr string, data []byte) (interface{}, error) { 36 | var v interface{} 37 | err := json.Unmarshal(data, &v) 38 | if err != nil { 39 | return nil, err 40 | } 41 | res, err := jmespath.Search(expr, v) 42 | return res, err 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-jmespath Benchmark 2 | 3 | This test suite benchmarks 4 | [go-jmespath](https://github.com/jmespath/go-jmespath) using the examples from 5 | [http://jmespath.org/examples.html](http://jmespath.org/examples.html). 6 | 7 | ### Usage and results: 8 | ``` 9 | $ sysctl -n machdep.cpu.brand_string 10 | Intel(R) Core(TM) i7-2675QM CPU @ 2.20GHz 11 | 12 | $ go test -bench=. 13 | 2016/03/14 16:39:10 Running 21 benchmarks 14 | PASS 15 | BenchmarkBaseline0-8 500000 2636 ns/op 16 | BenchmarkJMES0-8 100000 15477 ns/op 17 | BenchmarkBaseline1-8 300000 3949 ns/op 18 | BenchmarkJMES1-8 100000 19344 ns/op 19 | BenchmarkBaseline2-8 500000 3090 ns/op 20 | BenchmarkJMES2-8 100000 17193 ns/op 21 | BenchmarkBaseline3-8 200000 8405 ns/op 22 | BenchmarkJMES3-8 50000 28547 ns/op 23 | BenchmarkBaseline4-8 300000 4532 ns/op 24 | BenchmarkJMES4-8 100000 22110 ns/op 25 | BenchmarkBaseline5-8 300000 4603 ns/op 26 | BenchmarkJMES5-8 100000 21731 ns/op 27 | BenchmarkBaseline6-8 300000 4441 ns/op 28 | BenchmarkJMES6-8 100000 21583 ns/op 29 | BenchmarkBaseline7-8 300000 4466 ns/op 30 | BenchmarkJMES7-8 100000 21891 ns/op 31 | BenchmarkBaseline8-8 300000 4468 ns/op 32 | BenchmarkJMES8-8 100000 22417 ns/op 33 | BenchmarkBaseline9-8 200000 9900 ns/op 34 | BenchmarkJMES9-8 50000 26617 ns/op 35 | BenchmarkBaseline10-8 200000 10039 ns/op 36 | BenchmarkJMES10-8 50000 26763 ns/op 37 | BenchmarkBaseline11-8 200000 6691 ns/op 38 | BenchmarkJMES11-8 100000 23683 ns/op 39 | BenchmarkBaseline12-8 200000 10508 ns/op 40 | BenchmarkJMES12-8 50000 28987 ns/op 41 | BenchmarkBaseline13-8 300000 5968 ns/op 42 | BenchmarkJMES13-8 100000 21385 ns/op 43 | BenchmarkBaseline14-8 200000 7717 ns/op 44 | BenchmarkJMES14-8 50000 26349 ns/op 45 | BenchmarkBaseline15-8 200000 9999 ns/op 46 | BenchmarkJMES15-8 50000 28395 ns/op 47 | BenchmarkBaseline16-8 200000 10078 ns/op 48 | BenchmarkJMES16-8 50000 29548 ns/op 49 | BenchmarkBaseline17-8 200000 10094 ns/op 50 | BenchmarkJMES17-8 50000 31823 ns/op 51 | BenchmarkBaseline18-8 200000 12035 ns/op 52 | BenchmarkJMES18-8 50000 27628 ns/op 53 | BenchmarkBaseline19-8 200000 7866 ns/op 54 | BenchmarkJMES19-8 50000 25852 ns/op 55 | BenchmarkBaseline20-8 300000 5268 ns/op 56 | BenchmarkJMES20-8 50000 32575 ns/op 57 | ok github.com/raphael/benchjmes 78.074s 58 | ``` 59 | 60 | -------------------------------------------------------------------------------- /bench_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | "testing" 7 | ) 8 | 9 | var benchmarks = []struct { 10 | Data string 11 | Expr string 12 | }{ 13 | {`{"a": "foo", "b": "bar", "c": "baz"}`, `a`}, 14 | {`{"a": {"b": {"c": {"d": "value"}}}}`, `a.b.c.d`}, 15 | {`["a", "b", "c", "d", "e", "f"]`, `[1]`}, 16 | {`{"a": { 17 | "b": { 18 | "c": [ 19 | {"d": [0, [1, 2]]}, 20 | {"d": [3, 4]} 21 | ] 22 | } 23 | }}`, `a.b.c[0].d[1][0]`}, 24 | {`[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`, `[0:5]`}, 25 | {`[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`, `[5:10]`}, 26 | {`[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`, `[:5]`}, 27 | {`[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`, `[::2]`}, 28 | {`[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`, `[::-1]`}, 29 | {`{ 30 | "people": [ 31 | {"first": "James", "last": "d"}, 32 | {"first": "Jacob", "last": "e"}, 33 | {"first": "Jayden", "last": "f"}, 34 | {"missing": "different"} 35 | ], 36 | "foo": {"bar": "baz"} 37 | }`, `people[*].first`}, 38 | {`{ 39 | "people": [ 40 | {"first": "James", "last": "d"}, 41 | {"first": "Jacob", "last": "e"}, 42 | {"first": "Jayden", "last": "f"}, 43 | {"missing": "different"} 44 | ], 45 | "foo": {"bar": "baz"} 46 | }`, `people[:2].first`}, 47 | {`{ 48 | "ops": { 49 | "functionA": {"numArgs": 2}, 50 | "functionB": {"numArgs": 3}, 51 | "functionC": {"variadic": true} 52 | } 53 | }`, `ops.*.numArgs`}, 54 | {`{ 55 | "reservations": [ 56 | { 57 | "instances": [ 58 | {"state": "running"}, 59 | {"state": "stopped"} 60 | ] 61 | }, 62 | { 63 | "instances": [ 64 | {"state": "terminated"}, 65 | {"state": "runnning"} 66 | ] 67 | } 68 | ] 69 | }`, `reservations[*].instances[*].state`}, 70 | {`[ 71 | [0, 1], 72 | 2, 73 | [3], 74 | 4, 75 | [5, [6, 7]] 76 | ]`, `[]`}, 77 | {`{ 78 | "machines": [ 79 | {"name": "a", "state": "running"}, 80 | {"name": "b", "state": "stopped"}, 81 | {"name": "b", "state": "running"} 82 | ] 83 | }`, `machines[?state=='running'].name`}, 84 | {`{ 85 | "people": [ 86 | {"first": "James", "last": "d"}, 87 | {"first": "Jacob", "last": "e"}, 88 | {"first": "Jayden", "last": "f"}, 89 | {"missing": "different"} 90 | ], 91 | "foo": {"bar": "baz"} 92 | }`, `people[*].first | [0]`}, 93 | {`{ 94 | "people": [ 95 | { 96 | "name": "a", 97 | "state": {"name": "up"} 98 | }, 99 | { 100 | "name": "b", 101 | "state": {"name": "down"} 102 | }, 103 | { 104 | "name": "c", 105 | "state": {"name": "up"} 106 | } 107 | ] 108 | }`, `people[].[name, state.name]`}, 109 | {`{ 110 | "people": [ 111 | { 112 | "name": "a", 113 | "state": {"name": "up"} 114 | }, 115 | { 116 | "name": "b", 117 | "state": {"name": "down"} 118 | }, 119 | { 120 | "name": "c", 121 | "state": {"name": "up"} 122 | } 123 | ] 124 | }`, `people[].{Name: name, State: state.name}`}, 125 | {`{ 126 | "people": [ 127 | { 128 | "name": "b", 129 | "age": 30, 130 | "state": {"name": "up"} 131 | }, 132 | { 133 | "name": "a", 134 | "age": 50, 135 | "state": {"name": "down"} 136 | }, 137 | { 138 | "name": "c", 139 | "age": 40, 140 | "state": {"name": "up"} 141 | } 142 | ] 143 | }`, `length(people)`}, 144 | {`{ 145 | "people": [ 146 | { 147 | "name": "b", 148 | "age": 30 149 | }, 150 | { 151 | "name": "a", 152 | "age": 50 153 | }, 154 | { 155 | "name": "c", 156 | "age": 40 157 | } 158 | ] 159 | }`, `max_by(people, &age).name`}, 160 | {`{ 161 | "myarray": [ 162 | "foo", 163 | "foobar", 164 | "barfoo", 165 | "bar", 166 | "baz", 167 | "barbaz", 168 | "barfoobaz" 169 | ] 170 | }`, `myarray[?contains(@, 'foo') == ` + "`" + `true` + "`" + `]`}, 171 | } 172 | 173 | func benchmarkBaseline(expr, data string, b *testing.B) { 174 | for n := 0; n < b.N; n++ { 175 | var v interface{} 176 | err := json.Unmarshal([]byte(data), &v) 177 | if err != nil { 178 | panic(err) 179 | } 180 | if v == nil { 181 | log.Fatalf("%s on %v returned nil", expr, data) 182 | } 183 | } 184 | } 185 | 186 | func benchmarkJMES(expr, data string, b *testing.B) { 187 | for n := 0; n < b.N; n++ { 188 | v, err := Apply(expr, []byte(data)) 189 | if err != nil { 190 | panic(err) 191 | } 192 | if v == nil { 193 | log.Fatalf("%s on %v returned nil", expr, data) 194 | } 195 | } 196 | } 197 | 198 | func TestPrintBenchmarkTitle(t *testing.T) { log.Printf("Running %d benchmarks", len(benchmarks)) } 199 | 200 | func BenchmarkBaseline0(b *testing.B) { benchmarkBaseline(benchmarks[0].Expr, benchmarks[0].Data, b) } 201 | func BenchmarkJMES0(b *testing.B) { benchmarkJMES(benchmarks[0].Expr, benchmarks[0].Data, b) } 202 | 203 | func BenchmarkBaseline1(b *testing.B) { benchmarkBaseline(benchmarks[1].Expr, benchmarks[1].Data, b) } 204 | func BenchmarkJMES1(b *testing.B) { benchmarkJMES(benchmarks[1].Expr, benchmarks[1].Data, b) } 205 | 206 | func BenchmarkBaseline2(b *testing.B) { benchmarkBaseline(benchmarks[2].Expr, benchmarks[2].Data, b) } 207 | func BenchmarkJMES2(b *testing.B) { benchmarkJMES(benchmarks[2].Expr, benchmarks[2].Data, b) } 208 | 209 | func BenchmarkBaseline3(b *testing.B) { benchmarkBaseline(benchmarks[3].Expr, benchmarks[3].Data, b) } 210 | func BenchmarkJMES3(b *testing.B) { benchmarkJMES(benchmarks[3].Expr, benchmarks[3].Data, b) } 211 | 212 | func BenchmarkBaseline4(b *testing.B) { benchmarkBaseline(benchmarks[4].Expr, benchmarks[4].Data, b) } 213 | func BenchmarkJMES4(b *testing.B) { benchmarkJMES(benchmarks[4].Expr, benchmarks[4].Data, b) } 214 | 215 | func BenchmarkBaseline5(b *testing.B) { benchmarkBaseline(benchmarks[5].Expr, benchmarks[5].Data, b) } 216 | func BenchmarkJMES5(b *testing.B) { benchmarkJMES(benchmarks[5].Expr, benchmarks[5].Data, b) } 217 | 218 | func BenchmarkBaseline6(b *testing.B) { benchmarkBaseline(benchmarks[6].Expr, benchmarks[6].Data, b) } 219 | func BenchmarkJMES6(b *testing.B) { benchmarkJMES(benchmarks[6].Expr, benchmarks[6].Data, b) } 220 | 221 | func BenchmarkBaseline7(b *testing.B) { benchmarkBaseline(benchmarks[7].Expr, benchmarks[7].Data, b) } 222 | func BenchmarkJMES7(b *testing.B) { benchmarkJMES(benchmarks[7].Expr, benchmarks[7].Data, b) } 223 | 224 | func BenchmarkBaseline8(b *testing.B) { benchmarkBaseline(benchmarks[8].Expr, benchmarks[8].Data, b) } 225 | func BenchmarkJMES8(b *testing.B) { benchmarkJMES(benchmarks[8].Expr, benchmarks[8].Data, b) } 226 | 227 | func BenchmarkBaseline9(b *testing.B) { benchmarkBaseline(benchmarks[9].Expr, benchmarks[9].Data, b) } 228 | func BenchmarkJMES9(b *testing.B) { benchmarkJMES(benchmarks[9].Expr, benchmarks[9].Data, b) } 229 | 230 | func BenchmarkBaseline10(b *testing.B) { benchmarkBaseline(benchmarks[10].Expr, benchmarks[10].Data, b) } 231 | func BenchmarkJMES10(b *testing.B) { benchmarkJMES(benchmarks[10].Expr, benchmarks[10].Data, b) } 232 | 233 | func BenchmarkBaseline11(b *testing.B) { benchmarkBaseline(benchmarks[11].Expr, benchmarks[11].Data, b) } 234 | func BenchmarkJMES11(b *testing.B) { benchmarkJMES(benchmarks[11].Expr, benchmarks[11].Data, b) } 235 | 236 | func BenchmarkBaseline12(b *testing.B) { benchmarkBaseline(benchmarks[12].Expr, benchmarks[12].Data, b) } 237 | func BenchmarkJMES12(b *testing.B) { benchmarkJMES(benchmarks[12].Expr, benchmarks[12].Data, b) } 238 | 239 | func BenchmarkBaseline13(b *testing.B) { benchmarkBaseline(benchmarks[13].Expr, benchmarks[13].Data, b) } 240 | func BenchmarkJMES13(b *testing.B) { benchmarkJMES(benchmarks[13].Expr, benchmarks[13].Data, b) } 241 | 242 | func BenchmarkBaseline14(b *testing.B) { benchmarkBaseline(benchmarks[14].Expr, benchmarks[14].Data, b) } 243 | func BenchmarkJMES14(b *testing.B) { benchmarkJMES(benchmarks[14].Expr, benchmarks[14].Data, b) } 244 | 245 | func BenchmarkBaseline15(b *testing.B) { benchmarkBaseline(benchmarks[15].Expr, benchmarks[15].Data, b) } 246 | func BenchmarkJMES15(b *testing.B) { benchmarkJMES(benchmarks[15].Expr, benchmarks[15].Data, b) } 247 | 248 | func BenchmarkBaseline16(b *testing.B) { benchmarkBaseline(benchmarks[16].Expr, benchmarks[16].Data, b) } 249 | func BenchmarkJMES16(b *testing.B) { benchmarkJMES(benchmarks[16].Expr, benchmarks[16].Data, b) } 250 | 251 | func BenchmarkBaseline17(b *testing.B) { benchmarkBaseline(benchmarks[17].Expr, benchmarks[17].Data, b) } 252 | func BenchmarkJMES17(b *testing.B) { benchmarkJMES(benchmarks[17].Expr, benchmarks[17].Data, b) } 253 | 254 | func BenchmarkBaseline18(b *testing.B) { benchmarkBaseline(benchmarks[18].Expr, benchmarks[18].Data, b) } 255 | func BenchmarkJMES18(b *testing.B) { benchmarkJMES(benchmarks[18].Expr, benchmarks[18].Data, b) } 256 | 257 | func BenchmarkBaseline19(b *testing.B) { benchmarkBaseline(benchmarks[19].Expr, benchmarks[19].Data, b) } 258 | func BenchmarkJMES19(b *testing.B) { benchmarkJMES(benchmarks[19].Expr, benchmarks[19].Data, b) } 259 | 260 | func BenchmarkBaseline20(b *testing.B) { benchmarkBaseline(benchmarks[20].Expr, benchmarks[20].Data, b) } 261 | func BenchmarkJMES20(b *testing.B) { benchmarkJMES(benchmarks[20].Expr, benchmarks[20].Data, b) } 262 | --------------------------------------------------------------------------------