Skip to content

feat: add three libraries to benchmark #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 110 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,21 @@ The libraries tested are:
| [json-query](https://www.npmjs.com/package/json-query) | [![npm](https://img.shields.io/npm/dw/json-query.svg)](https://www.npmjs.com/package/json-query) | ![GitHub last commit](https://img.shields.io/github/last-commit/mmckegg/json-query.svg) |
| [jsonpath-plus](https://www.npmjs.com/package/jsonpath-plus) | [![npm](https://img.shields.io/npm/dw/jsonpath-plus.svg)](https://www.npmjs.com/package/jsonpath-plus) | ![GitHub last commit](https://img.shields.io/github/last-commit/s3u/JSONPath.svg) |
| [jsonpath](https://www.npmjs.com/package/jsonpath) | [![npm](https://img.shields.io/npm/dw/jsonpath.svg)](https://www.npmjs.com/package/jsonpath) | ![GitHub last commit](https://img.shields.io/github/last-commit/dchester/jsonpath.svg) |
| [json-p3](https://www.npmjs.com/package/json-p3) | [![npm](https://img.shields.io/npm/dw/json-p3.svg)](https://www.npmjs.com/package/json-p3) | ![GitHub last commit](https://img.shields.io/github/last-commit/jg-rp/json-p3.svg) |
| [js-json-go](https://www.npmjs.com/package/js-json-go) | [![npm](https://img.shields.io/npm/dw/js-json-go.svg)](https://www.npmjs.com/package/jg-json-go) | ![GitHub last commit](https://img.shields.io/github/last-commit/JG-1202/js-json-go.svg) |
| [json-power-query](https://www.npmjs.com/package/json-power-query) | [![npm](https://img.shields.io/npm/dw/json-power-query.svg)](https://www.npmjs.com/package/json-power-query) | ![GitHub last commit](https://img.shields.io/github/last-commit/TotalTechGeek/json-power-query.svg) |
| [JSONStream](https://www.npmjs.com/package/JSONStream) | [![npm](https://img.shields.io/npm/dw/JSONStream.svg)](https://www.npmjs.com/package/JSONStream) | ![GitHub last commit](https://img.shields.io/github/last-commit/dominictarr/JSONStream.svg) |
| [oboe](https://www.npmjs.com/package/oboe) | [![npm](https://img.shields.io/npm/dw/oboe.svg)](https://www.npmjs.com/package/oboe) | ![GitHub last commit](https://img.shields.io/github/last-commit/jimhigson/oboe.js.svg) |
| [map-filter-reduce](https://www.npmjs.com/package/map-filter-reduce) | [![npm](https://img.shields.io/npm/dw/map-filter-reduce.svg)](https://www.npmjs.com/package/map-filter-reduce) | ![GitHub last commit](https://img.shields.io/github/last-commit/dominictarr/map-filter-reduce.svg) |
| [map-filter-reduce](https://www.npmjs.com/package/map-filter-reduce) | [![npm](https://img.shields.io/npm/dw/map-filter-reduce.svg)](https://www.npmjs.com/package/map-filter-reduce) | ![GitHub last commit](https://img.shields.io/github/last-commit/jg-rp/json-p3.svg) |

`jsonpath-plus` and `jsonpath` use the [XPath for Json Specification](https://goessner.net/articles/JsonPath).
`json-query` has its own custom DSL. `JSONStream`, `oboe`, and `map-filter-reduce` are streaming libraries, though I've had varying success in making them anywhere near as performant.
`json-query`, `json-p3` and `json-js-go` has its own custom DSL. `JSONStream`, `oboe`, and `map-filter-reduce` are streaming libraries, though I've had varying success in making them anywhere near as performant.

## How to run

```
npm install
npm run perf
pnpm install
pnpm run perf
```

### Method Explaination
Expand All @@ -34,58 +37,82 @@ The performance test runs three queries on each of the libraries. All three quer

### Results

Ran using Macbook Pro, 2.2 GHz Intel Core i7, 16 GB 2400 MHz DDR4
Ran using Macbook Pro, Apple M2 Max 12c, 32GB RAM, Node v21.4.0

```
$ npm run perf
$ pnpm run perf

> [email protected] perf /Users/andrew/Code/scratchwork/perf-json-querying
> node --max-old-space-size=4096 src
> [email protected] perf /Users/jbergstroem/wrk/oss/json-querying-performance-testing
> node --max-old-space-size=4096 --expose-gc src

smallCityLots 49998 items.
mediumCityLots 99998 items.
largeCityLots 206560 items.

smallCityLots:
- json-query:
- shallow took 0.0176 seconds.
- deep took 0.0502 seconds.
- conditional took 0.0408 seconds.
- shallow took 0.0047 seconds.
- deep took 0.0048 seconds.
- conditional took 0.0062 seconds.
- jsonpath-plus:
- shallow took 0.4146 seconds.
- deep took 0.4239 seconds.
- conditional took 0.326 seconds.
- shallow took 0.1355 seconds.
- deep took 0.1339 seconds.
- conditional took 0.0342 seconds.
- jsonpath:
- shallow took 1.1165 seconds.
- deep took 4.4373 seconds.
- conditional took 0.1387 seconds.
- shallow took 0.3711 seconds.
- deep took 2.3432 seconds.
- conditional took 0.0116 seconds.
- json-p3:
- shallow took 0.6913 seconds.
- deep took 0.5962 seconds.
- conditional took 0.029 seconds.
- js-json-go:
- shallow took 0.0434 seconds.
- deep took 0.0399 seconds.
- conditional took 0.0616 seconds.
- json-power-query:
- shallow took 0.0029 seconds.
- deep took 0.0028 seconds.
- conditional took 0.0037 seconds.
- JSONStream:
- shallow took 20.5 seconds.
- deep took 23.5372 seconds.
- shallow took 0.9522 seconds.
- deep took 0.9774 seconds.
- oboe:
- shallow took 25.0891 seconds.
- deep took 32.5883 seconds.
- shallow took 1.1483 seconds.
- deep took 1.1847 seconds.
- map-filter-reduce:

mediumCityLots:
- json-query:
- shallow took 0.0489 seconds.
- deep took 0.0732 seconds.
- conditional took 0.0488 seconds.
- shallow took 0.0055 seconds.
- deep took 0.0091 seconds.
- conditional took 0.0083 seconds.
- jsonpath-plus:
- shallow took 0.8285 seconds.
- deep took 0.8567 seconds.
- conditional took 0.6074 seconds.
- shallow took 0.2546 seconds.
- deep took 0.272 seconds.
- conditional took 0.0593 seconds.
- jsonpath:
- shallow took 2.2047 seconds.
- deep took 37.187 seconds.
- conditional took 0.2852 seconds.
- shallow took 0.7684 seconds.
- deep took 8.2911 seconds.
- conditional took 0.0192 seconds.
- json-p3:
- shallow took 1.4808 seconds.
- deep took 1.2317 seconds.
- conditional took 0.0475 seconds.
- js-json-go:
- shallow took 0.0712 seconds.
- deep took 0.0634 seconds.
- conditional took 0.1034 seconds.
- json-power-query:
- shallow took 0.0051 seconds.
- deep took 0.0044 seconds.
- conditional took 0.0038 seconds.
- JSONStream:
- shallow took 199.4793 seconds.
- deep took 5.0332 seconds.
- shallow took 2.0166 seconds.
- deep took 2.048 seconds.
- oboe:
- shallow took 27.819 seconds.
- deep took 77.9259 seconds.
- shallow took 2.4415 seconds.
- deep took 2.4524 seconds.
- map-filter-reduce:

largeCityLots:
Expand All @@ -94,19 +121,31 @@ json-query shallow failed, RangeError: Maximum call stack size exceeded.
json-query deep failed, RangeError: Maximum call stack size exceeded.
json-query conditional failed, RangeError: Maximum call stack size exceeded.
- jsonpath-plus:
- shallow took 2.3345 seconds.
- deep took 2.472 seconds.
- conditional took 3.1351 seconds.
- shallow took 0.7001 seconds.
- deep took 0.7331 seconds.
- conditional took 0.1226 seconds.
- jsonpath:
- shallow took 8.509 seconds.
- deep took 252.9623 seconds.
- conditional took 0.7586 seconds.
- shallow took 2.1981 seconds.
- deep took 33.633 seconds.
- conditional took 0.0452 seconds.
- json-p3:
- shallow took 5.3844 seconds.
- deep took 5.3054 seconds.
- conditional took 0.1007 seconds.
- js-json-go:
- shallow took 0.1173 seconds.
- deep took 0.12 seconds.
- conditional took 0.2242 seconds.
- json-power-query:
- shallow took 0.0117 seconds.
- deep took 0.0113 seconds.
- conditional took 0.0093 seconds.
- JSONStream:
- shallow took 54.8295 seconds.
- deep took 146.2962 seconds.
- shallow took 6.0252 seconds.
- deep took 6.0345 seconds.
- oboe:
- shallow took 148.8824 seconds.
- deep took 216.7555 seconds.
- shallow took 7.341 seconds.
- deep took 7.2204 seconds.
- map-filter-reduce:


Expand All @@ -115,35 +154,44 @@ summary:

smallCityLots
┌───────────────────┬───────────────────┬───────────────────┬───────────────────┐
(index)shallowdeepconditional
(index)shallowdeepconditional
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ json-query │ 0.0176 │ 0.0502 │ 0.0408 │
│ jsonpath-plus │ 0.4146 │ 0.4239 │ 0.326 │
│ jsonpath │ 1.1165 │ 4.4373 │ 0.1387 │
│ JSONStream │ 20.5 │ 23.5372 │ 'not possible' │
│ oboe │ 25.0891 │ 32.5883 │ 'not possible' │
│ json-query │ 0.0047 │ 0.0048 │ 0.0062 │
│ jsonpath-plus │ 0.1355 │ 0.1339 │ 0.0342 │
│ jsonpath │ 0.3711 │ 2.3432 │ 0.0116 │
│ json-p3 │ 0.6913 │ 0.5962 │ 0.029 │
│ js-json-go │ 0.0434 │ 0.0399 │ 0.0616 │
│ json-power-query │ 0.0029 │ 0.0028 │ 0.0037 │
│ JSONStream │ 0.9522 │ 0.9774 │ 'not possible' │
│ oboe │ 1.1483 │ 1.1847 │ 'not possible' │
│ map-filter-reduce │ 'not implemented' │ 'not implemented' │ 'not implemented' │
└───────────────────┴───────────────────┴───────────────────┴───────────────────┘
mediumCityLots
┌───────────────────┬───────────────────┬───────────────────┬───────────────────┐
(index)shallowdeepconditional
(index)shallowdeepconditional
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ json-query │ 0.0489 │ 0.0732 │ 0.0488 │
│ jsonpath-plus │ 0.8285 │ 0.8567 │ 0.6074 │
│ jsonpath │ 2.2047 │ 37.187 │ 0.2852 │
│ JSONStream │ 199.4793 │ 5.0332 │ 'not possible' │
│ oboe │ 27.819 │ 77.9259 │ 'not possible' │
│ json-query │ 0.0055 │ 0.0091 │ 0.0083 │
│ jsonpath-plus │ 0.2546 │ 0.272 │ 0.0593 │
│ jsonpath │ 0.7684 │ 8.2911 │ 0.0192 │
│ json-p3 │ 1.4808 │ 1.2317 │ 0.0475 │
│ js-json-go │ 0.0712 │ 0.0634 │ 0.1034 │
│ json-power-query │ 0.0051 │ 0.0044 │ 0.0038 │
│ JSONStream │ 2.0166 │ 2.048 │ 'not possible' │
│ oboe │ 2.4415 │ 2.4524 │ 'not possible' │
│ map-filter-reduce │ 'not implemented' │ 'not implemented' │ 'not implemented' │
└───────────────────┴───────────────────┴───────────────────┴───────────────────┘
largeCityLots
┌───────────────────┬───────────────────┬───────────────────┬───────────────────┐
(index)shallowdeepconditional
(index)shallowdeepconditional
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ json-query │ 'failed' │ 'failed' │ 'failed' │
│ jsonpath-plus │ 2.3345 │ 2.472 │ 3.1351 │
│ jsonpath │ 8.509 │ 252.9623 │ 0.7586 │
│ JSONStream │ 54.8295 │ 146.2962 │ 'not possible' │
│ oboe │ 148.8824 │ 216.7555 │ 'not possible' │
│ json-query │ 'failed' │ 'failed' │ 'failed' │
│ jsonpath-plus │ 0.7001 │ 0.7331 │ 0.1226 │
│ jsonpath │ 2.1981 │ 33.633 │ 0.0452 │
│ json-p3 │ 5.3844 │ 5.3054 │ 0.1007 │
│ js-json-go │ 0.1173 │ 0.12 │ 0.2242 │
│ json-power-query │ 0.0117 │ 0.0113 │ 0.0093 │
│ JSONStream │ 6.0252 │ 6.0345 │ 'not possible' │
│ oboe │ 7.341 │ 7.2204 │ 'not possible' │
│ map-filter-reduce │ 'not implemented' │ 'not implemented' │ 'not implemented' │
└───────────────────┴───────────────────┴───────────────────┴───────────────────┘
```
55 changes: 55 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": false,
"correctness": {
"all": false,
"noUnusedVariables": "error",
"noPrecisionLoss": "error"
},
"suspicious": {
"all": false,
"noControlCharactersInRegex": "error"
}
},
"ignore": ["datasets"]
},
"files": {
"ignoreUnknown": true
},
"formatter": {
"enabled": true,
"formatWithErrors": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 120,
"ignore": ["datasets"]
},
"javascript": {
"formatter": {
"enabled": true,
"quoteStyle": "single",
"arrowParentheses": "asNeeded",
"trailingComma": "all",
"lineEnding": "lf"
},
"parser": {
"unsafeParameterDecoratorsEnabled": true
}
},
"json": {
"formatter": {
"enabled": true
}
}
}
Loading