pysimdjson Documentation

repository·master·Indexed 20 days ago

https://github.com/tktech/pysimdjson

High-performance Python bindings for the SIMD-accelerated simdjson parser. It provides a drop-in API compatible with the built-in json module and a Native API for lazy evaluation of JSON documents using Object and Array types. The library supports Python 3.9 through 3.12 on OS X, Linux, and Windows, featuring automatic fallback to a standard parser on systems where SIMD instructions are unavailable.

Tokens
2.4K
Snippets
13
Records
15
Agent score
73%

What's inside pysimdjson

  1. Overview of pysimdjson

    master

    pysimdjson provides Python bindings for the simdjson project, which is a SIMD-accelerated JSON parser. It is designed to be safe for all environments: if SIMD instructions are unavailable on the host CPU, the library automatically falls back to a standard parser.

    Supported platforms include OS X, Linux, and Windows, with support for Python versions 3.9 through 3.12.

  2. Use the Native API for high-performance JSON parsing

    master

    The Native API in pysimdjson provides significant performance improvements over the builtin-compatible API when you only need to access specific parts of a JSON document.

    Instead of immediately converting the entire JSON structure into Python objects, the Native API returns Object and Array types. These act as 'fake' dicts and lists that delay the creation of actual Python objects until the specific elements are accessed. This lazy evaluation minimizes overhead for large documents.

    import simdjson
    
    parser = simdjson.Parser()
    # Parsing returns Object or Array types which delay Python object creation
    doc = parser.parse('{"key": "value"}')
    print(doc['key'])
  3. Use the .mini property to retrieve minified JSON strings

    master

    If you need to extract a specific property from a document but want to forward or store the rest of the document as a raw string (e.g., in a message router or database), use the .mini property on Object or Array instances.

    This returns the entire content of that object/array as a minified Python str. This allows you to access metadata (like a routing key) without ever converting the large payload into a heavy Python object structure.

    import simdjson
    
    # Example: Extracting a key and getting the rest as a minified string
    parser = simdjson.Parser()
    doc = parser.parse(request_data)
    
    key = doc['key']          # Only 'key' is turned into a Python object
    payload = doc.mini       # The rest is returned as a minified string
  4. Use the drop-in API for JSON parsing

    master

    The simdjson module provides load and loads functions designed as drop-in replacements for the built-in Python json module. These functions allow you to parse JSON data with minimal code changes. While they are slightly slower than using the explicit Parser interface, they are optimized for ease of use and

    import simdjson
    
    # Parsing from a string
    data = simdjson.loads('{"key": "value"}')
    
    # Parsing from a file-like object
    with open('data.json', 'r') as f:
        data = simdjson.load(f)
  5. Re-use the Parser instance to reduce allocations

    master

    When processing many JSON documents, do not create a new simdjson.Parser() for every document. Instead, instantiate a single parser and reuse it for multiple calls to .parse().

    Reusing the parser allows it to reuse its internal buffers, drastically reducing the number of memory allocations. If a new document is larger than the existing buffer, the parser will automatically grow the buffer to fit.

    import simdjson
    
    # Efficient: Reuse the same parser instance
    parser = simdjson.Parser()
    
    for i in range(100):
        # The parser reuses its internal buffer across iterations
        doc = parser.parse(b'{"a": "b"}')
        # Explicitly delete doc if necessary to free the reference to the parsed content
        del doc
  6. Avoid full document loading for better performance

    master

    To achieve maximum performance, avoid using simdjson.loads() or simdjson.load() if you only need specific parts of a JSON document. The majority of overhead in Python JSON libraries comes from creating Python objects for the entire document.

    Instead, use one of these two methods to access specific data without parsing the whole structure into Python objects:

    1. Indexing/Subscripting: Access elements directly via keys or indices (e.g., doc['key'][0]).
    2. JSON Pointers: Use the at_pointer() method with a JSON pointer string (e.g., doc.at_pointer('/path/to/element')).

    Both methods are significantly faster because they avoid the overhead of constructing Python objects for the parts of the document you ignore.

    import simdjson
    parser = simdjson.Parser()
    doc = parser.parse(b'{"res": [{"name": "first"}, {"name": "second"}]}')
    
    # Method 1: Subscripting
    assert doc['res'][1]['name'] == 'second'
    
    # Method 2: JSON Pointers
    assert doc.at_pointer('/res/1/name') == 'second'
  7. Build for debugging, coverage, or forced rebuilds

    master

    When working with Cython, you can use additional environment variables to modify the build process:

    • Debug/Coverage: To build with support for linetracing and coverage, use BUILD_FOR_DEBUG=1 along with BUILD_WITH_CYTHON=1.
    • Force Rebuild: To prevent the build from reusing an existing .so file and force Cython to rebuild it, use FORCE_REBUILD=1 along with BUILD_WITH_CYTHON=1.
    # Build for debug/coverage
    BUILD_WITH_CYTHON=1 BUILD_FOR_DEBUG=1 python setup.py develop
    
    # Force a full rebuild
    BUILD_WITH_CYTHON=1 FORCE_REBUILD=1 python setup.py develop
  8. Install pysimdjson from source

    master

    If you want to force an installation from source (for example, to use a newer compiler than the one used for the pre-compiled binary wheels), use the --no-binary :all: flag.

    Note: When installing from source, a C++11 (or better) compiler is required to build the underlying simdjson library.

    pip install pysimdjson --no-binary :all:
  9. Install pysimdjson via pip

    master

    You can install pysimdjson using pip. If binary wheels are available for your platform and Python version, no additional requirements are needed.

    Binary wheels are provided for CPython 3.9 through 3.12 on the following architectures:

    • x86_64: OS X, Windows, Linux
    • ARM64: Linux
    • PowerPC: Linux
    pip install pysimdjson
  10. Install development and testing dependencies

    master

    To set up a development environment with all necessary testing dependencies, install the package in editable mode using the [test] extra:

    pip install -e ".[test]"

    To run the test suite, use pytest. For slow integration tests, use the --runslow flag:

    pytest
    # or for slow integration tests
    pytest --runslow
  11. Force Cython regeneration during build

    master

    By default, setup.py uses the pre-generated csimdjson.cpp to avoid requiring Cython as an install-time dependency. If you need to regenerate csimdjson.cpp from the .pyx and .pxd files, set the BUILD_WITH_CYTHON=1 environment variable when running setup.py develop.

    BUILD_WITH_CYTHON=1 python setup.py develop
  12. Optimize loading homogeneous arrays into NumPy

    master
    For high-performance numerical processing, pysimdjson provides optimizations for loading homogeneous arrays into numpy. Using simdjson.Array.as_buffer() is typically at least 8x faster than standard Python methods for converting JSON arrays to NumPy-compatible buffers.