Skip to content

purejq 0.2.0 — static binding, fast paths, real benchmarks

Choose a tag to compare

@adam2go adam2go released this 10 Jun 12:46

A second performance round on top of 0.1.1, plus a benchmark suite that measures purejq against both the jq PyPI package (C bindings) and the jq binary.

Headline numbers

Embedded in Python (100k objects, in-process) — purejq is 6–40x faster than the jq C-binding package, which pays a full JSON serialization round-trip per call:

workload purejq jq PyPI (C bindings)
filter + count 56 ms 485 ms
group_by 114 ms 765 ms
transform + sort 141 ms 943 ms

End-to-end CLI (93 MB file, 1M objects) — purejq beats the C jq binary on parse-dominated runs:

workload purejq jq 1.8
single lookup 0.5 s 1.6 s
filter + count 1.1 s 2.0 s
group_by 2.3 s 4.0 s

PyPy: another 2–9x on top (map+aggregate: 2 ms).

Engine changes

  • Static call binding: names never redefined in a program are resolved to their prelude/Python builtin at compile time
  • Single-output fast paths: constants, variables, field chains and arithmetic over them compile to plain callables; binops, object literals, pipes, and builtin arguments (select/map/sort_by keys) skip generator machinery
  • reduce/foreach reuse one environment per fold

Conformance unchanged: 751/781 (96.2%) of jq's official test suite. Run the benchmarks yourself: python3 tools/bench.py 1000000.