Skip to content

ferrantejake/json-parse-benchmark

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rust JSON Parser Benchmarks

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)

Performance Summary

Based on extensive benchmarking, comparing the fastest JavaScript implementation (usually JSON.parse) against the fastest Rust implementation (usually serde_json):

  1. Rust serde_json consistently 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
  2. 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
  3. Rust simd-json shows 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
  4. JS simdjson has the lowest performance among the tested implementations

Implementation Details

This project provides three JSON validation functions for native Node.js:

  • parseJson - Uses serde_json (fastest implementation)
  • parseJsonSerde - Uses serde_json
  • parseJsonSimd - Uses simd-json

All functions simply validate JSON and return the original string if valid or an error message if invalid.

Key Optimizations

  1. Zero-copy validation - Using serde_json::value::RawValue to validate JSON without constructing a full DOM
  2. Native compilation - Leveraging Rust's performance advantages
  3. Simple return values - Returning the original string directly when valid

Usage

Node.js with native bindings

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"}');

Running Benchmarks

npm install
npm run benchmark

Scripts

  • npm run build - Build the Rust code and generate Node.js bindings
  • npm run benchmark - Build and run native performance tests
  • npm run clean - Clean build artifacts

Sample Native Results

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)
---------------------------------------------------------------------------------------------------------------------------------------------------

WebAssembly Support

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:

  1. A working Rust installation with rustup
  2. The wasm32-unknown-unknown target installed: rustup target add wasm32-unknown-unknown
  3. 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.

Conclusion

After extensive testing and comparison, we've found that:

  1. serde_json is the clear winner: Despite expectations that SIMD-accelerated libraries would offer superior performance, the standard serde_json library with its zero-copy validation approach consistently outperforms all alternatives.

  2. Native JSON.parse is surprisingly efficient: The JavaScript engine's built-in JSON.parse function performs quite well - usually 2-4x faster than third-party JS libraries like simdjson-js.

  3. 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.

  4. 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.

  5. Simple approach works best: Our best-performing solution is also the simplest - using serde_json::value::RawValue for 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.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published