This project compares the performance of various JSON parsing libraries across JavaScript and Rust:
- JavaScript: Native
JSON.parse - JavaScript: simdjson-js
- Rust: serde_json (Native)
- Rust: simd-json (Native)
- WebAssembly: Support prepared but requires additional setup (see WASM section below)
Based on extensive benchmarking, comparing the fastest JavaScript implementation (usually JSON.parse) against the fastest Rust implementation (usually serde_json):
-
Rust
serde_jsonconsistently outperforms all implementations:- Up to 59% faster than native JSON.parse for small files (1000 iterations)
- Up to 53.8% faster than JSON.parse for large array files (single parse)
- Up to 42% faster than JSON.parse for large object files (single parse)
- Significantly faster than both JS simdjson and Rust simd-json in all tests
-
Native JSON.parse performs well, but is still outpaced by Rust:
- 2-4x faster than JS simdjson for single parse operations
- 2-3x faster than JS simdjson for multiple iterations
-
Rust
simd-jsonshows good performance compared to JavaScript implementations:- Faster than both JS implementations
- Slightly slower than Rust
serde_json - Requires more memory operations due to in-place parsing
-
JS
simdjsonhas the lowest performance among the tested implementations
This project provides three JSON validation functions for native Node.js:
parseJson- Usesserde_json(fastest implementation)parseJsonSerde- Usesserde_jsonparseJsonSimd- Usessimd-json
All functions simply validate JSON and return the original string if valid or an error message if invalid.
- Zero-copy validation - Using
serde_json::value::RawValueto validate JSON without constructing a full DOM - Native compilation - Leveraging Rust's performance advantages
- Simple return values - Returning the original string directly when valid
const parser = require('./index.js');
// Validate JSON using the fastest method (serde_json)
const result = parser.parseJson('{"key": "value"}');
// Compare with other implementations
const serde = parser.parseJsonSerde('{"key": "value"}');
const simd = parser.parseJsonSimd('{"key": "value"}');npm install
npm run benchmark
npm run build- Build the Rust code and generate Node.js bindingsnpm run benchmark- Build and run native performance testsnpm run clean- Clean build artifacts
JSON Parsing Performance Comparison
File Operation JSON.parse JS SIMD Rust Serde Rust SIMD WASM Serde WASM SIMD Difference vs best JS
---------------------------------------------------------------------------------------------------------------------------------------------------
sample.json Single Parse 0.014 0.125 0.017 0.044 0.007 0.003 76.4% faster (WASM SIMD)
sample.json 1000 Iterations 2.460 6.101 0.953 2.337 1.874 1.831 61.2% faster (Rust Serde)
---------------------------------------------------------------------------------------------------------------------------------------------------
sample-big-array.json Single Parse 2.995 9.375 1.242 3.554 2.352 2.381 58.5% faster (Rust Serde)
sample-big-array.json 1000 Iterations 3237.041 7560.244 1243.493 3218.993 2318.924 2279.372 61.6% faster (Rust Serde)
---------------------------------------------------------------------------------------------------------------------------------------------------
sample-big-object.json Single Parse 0.143 0.592 0.099 0.177 0.124 0.114 30.8% faster (Rust Serde)
sample-big-object.json 1000 Iterations 107.956 241.441 76.203 99.806 107.102 107.340 29.4% faster (Rust Serde)
---------------------------------------------------------------------------------------------------------------------------------------------------
The code for WebAssembly is already prepared in this repository, but there seems to be an issue with the Rust installation that prevents building WASM targets. To use the WASM version, you'll need:
- A working Rust installation with
rustup - The wasm32-unknown-unknown target installed:
rustup target add wasm32-unknown-unknown - The wasm-pack tool installed:
cargo install wasm-pack
Once you have these prerequisites, you can build and test the WASM version using:
./wasm-build.sh
npm run serve
The WASM implementation should provide performance between native Rust and JavaScript, depending on the browser and specific use case.
After extensive testing and comparison, we've found that:
-
serde_jsonis the clear winner: Despite expectations that SIMD-accelerated libraries would offer superior performance, the standardserde_jsonlibrary with its zero-copy validation approach consistently outperforms all alternatives. -
Native JSON.parse is surprisingly efficient: The JavaScript engine's built-in
JSON.parsefunction performs quite well - usually 2-4x faster than third-party JS libraries likesimdjson-js. -
Native bindings offer significant benefits: When maximum performance is required, using Rust with native Node.js bindings provides substantial improvements over pure JavaScript solutions - up to 59% faster than even the best JS implementation.
-
Zero-copy validation is key: A major factor in the performance advantage is avoiding unnecessary allocations and conversions when all that's needed is validation.
-
Simple approach works best: Our best-performing solution is also the simplest - using
serde_json::value::RawValuefor validation without constructing a full DOM.
These findings challenge the common assumption that more complex or specialized libraries will always provide better performance. In this case, a straightforward implementation with the standard library outperforms more specialized approaches.