Skip to main content

A high-performance Python JSON library that fully leverages modern processor capabilities.

Project description

ssrJSON

A SIMD boosted high-performance and correct Python JSON library that fully leverages modern processor capabilities.

Introduction

ssrJSON is a Python JSON library that leverages modern hardware capabilities to achieve peak performance, implemented primarily in C with some components written in C++. It offers a fully compatible interface to Python’s standard json module, making it a seamless drop-in replacement, while providing exceptional performance for JSON encoding and decoding.

How Fast is ssrJSON?

TL;DR: ssrJSON is faster than or nearly as fast as orjson (which announces itself as the fastest Python library for JSON) on most benchmark cases.

ssrjson.dumps() is about 4x-26x as fast as json.dumps() (Python3.13, x86-64, AVX2). ssrjson.loads() is about 2x-8x as fast as json.loads() for str input and is about 2x-8x as fast as json.loads() for bytes input (Python3.13, x86-64, AVX2). ssrJSON also provides ssrjson.dumps_to_bytes(), which encode Python objects directly to bytes object using SIMD instructions, similar to orjson.dumps but without calling slow CPython functions to do the UTF-8 encoding. Typically, ssrJSON is capable of processing non-ASCII strings directly without invoking any slow CPython UTF-8 encoding and decoding interfaces, eliminating the need for intermediate representations. Furthermore, the underlying implementation leverages SIMD acceleration to optimize this process. Details of benchmarking can be found in the benchmark repository. If you wish to run the benchmark tests yourself, you can execute the following commands:

pip install ssrjson-benchmark
python -m ssrjson_benchmark

This will generate a PDF report of the results. If you choose to, you may submit this report to the benchmark repository, allowing others to view the performance metrics of ssrJSON on your device.

Design Goal

The design goal of ssrJSON is to provide a straightforward and highly compatible approach to replace the inherently slower Python standard JSON encoding and decoding implementation with a significantly more efficient and high-performance alternative. If your module exclusively utilizes dumps and loads, you can replace the current JSON implementation by importing ssrJSON as import ssrjson as json. To facilitate this, ssrJSON maintains compatibility with the argument formats of json.dumps and json.loads; however, it does not guarantee identical results to the standard JSON module, as many features are either intentionally omitted or not yet supported. For further information, please refer to the section Implementation Details.

Current Status

ssrJSON is currently operational, although some potentially useful features have yet to be implemented. The development of ssrJSON is still actively ongoing, and your code contributions are highly appreciated.

How To Install

Pre-built wheels are available on PyPI.

pip install ssrjson

Note: ssrJSON requires at least SSE4.2 on x86-64 (x86-64-v2). ssrJSON does not work with Python implementations other than CPython. Currently supported CPython versions are 3.9, 3.10, 3.11, 3.12, 3.13, 3.14. For Python 3.14, you need to build it from source.

Build From Source

Since ssrJSON utilizes LLVM's vectorization extensions, it requires compilation with Clang and cannot be compiled in GCC or pure MSVC environments. On Windows, clang-cl can be used for this purpose. Build can be easily done by the following commands (make sure CMake, Clang and Python are already installed)

# On Linux:
# export CC=clang
# export CXX=clang++
mkdir build
cmake -S . -B build  # On Windows, configure with `cmake -T ClangCL`
cmake --build build

Usage

Basic

>>> import ssrjson
>>> ssrjson.dumps({"key": "value"})
'{"key":"value"}'
>>> ssrjson.loads('{"key":"value"}')
{'key': 'value'}
>>> ssrjson.dumps_to_bytes({"key": "value"})
b'{"key":"value"}'
>>> ssrjson.loads(b'{"key":"value"}')
{'key': 'value'}

Indent

ssrJSON only supports encoding with indent = 2, 4 or no indent (indent=0). When indent is used, a space is inserted between each key and value.

>>> import ssrjson
>>> ssrjson.dumps({"a": "b", "c": {"d": True}, "e": [1, 2]})
'{"a":"b","c":{"d":true},"e":[1,2]}'
>>> print(ssrjson.dumps({"a": "b", "c": {"d": True}, "e": [1, 2]}, indent=2))
{
  "a": "b",
  "c": {
    "d": true
  },
  "e": [
    1,
    2
  ]
}
>>> print(ssrjson.dumps({"a": "b", "c": {"d": True}, "e": [1, 2]}, indent=4))
{
    "a": "b",
    "c": {
        "d": true
    },
    "e": [
        1,
        2
    ]
}
>>> ssrjson.dumps({"a": "b", "c": {"d": True}, "e": [1, 2]}, indent=3)
Traceback (most recent call last):
  File "<python-input>", line 1, in <module>
    ssrjson.dumps({"a": "b", "c": {"d": True}, "e": [1, 2]}, indent=3)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: indent must be 0, 2, or 4

Other Arguments Supported by Python's json

Arguments like ensure_ascii, parse_float provided by json can be recognized but ignored by design.

The functionality of object_hook in json.loads will be supported in future.

Implementation Details

The implementations of ssrJSON's dumps and loads functions are designed to perform in-place processing as much as possible, avoiding intermediate representations. The dumps function employs SIMD instructions for rapid encoding in a single step. Similarly, dumps_to_bytes uses SIMD to efficiently handle both UTF-8 encoding and JSON serialization at the same time. With some modifications, the code used by dumps_to_bytes can also serve as a SIMD-accelerated replacement for str.encode("utf-8").

The implementation of ssrJSON's loads draws inspiration from yyjson, and also orjson's caching algorithm for short dictionary keys. When the input type is str, loads avoids any UTF-8 encoding or decoding operations on non-ASCII strings. If the input is bytes, loads utilizes a modified string decoding algorithm based on yyjson. The main control flow and number decoding of loads are also modified from yyjson.

Generally, ssrjson.dumps behaves like json.dumps with ensure_ascii=False, and ssrjson.loads behaves like json.loads.

Features

Below we explain some feature details of ssrJSON, which might be different from json module or other third-party JSON libraries.

Strings

Code points within the range [0xd800, 0xdfff] cannot be represented in UTF-8 encoding, and the standard JSON specification typically prohibits the presence of such characters. However, since Python's str type is not encoded in UTF-8, ssrJSON aims to maintain compatibility with the Python json module's behavior, while other third-party Python JSON libraries may complain about this. In contrast, for the dumps_to_bytes function, which encodes output in UTF-8, the inclusion of these characters in the input is considered invalid.

>>> s = chr(0xd800)
>>> (json.dumps(s, ensure_ascii=False) == '"' + s + '"', json.dumps(s, ensure_ascii=False))
(True, '"\ud800"')
>>> (ssrjson.dumps(s) == '"' + s + '"', ssrjson.dumps(s))
(True, '"\ud800"')
>>> ssrjson.dumps_to_bytes(s)
Traceback (most recent call last):
  File "<python-input>", line 1, in <module>
    ssrjson.dumps_to_bytes(s)
    ~~~~~~~~~~~~~~~~~~~~~~^^^
ssrjson.JSONEncodeError: Cannot encode unicode character in range [0xd800, 0xdfff] to utf-8
>>> json.loads(json.dumps(s, ensure_ascii=False)) == s
True
>>> ssrjson.loads(ssrjson.dumps(s)) == s
True

Integers

ssrjson.dumps can only handle integers that can be expressed by either uint64_t or int64_t in C.

>>> ssrjson.dumps(-(1<<63)-1)
Traceback (most recent call last):
  File "<python-input>", line 1, in <module>
    ssrjson.dumps(-(1<<63)-1)
    ~~~~~~~~~~~~~^^^^^^^^^^^^
ssrjson.JSONEncodeError: convert value to long long failed
>>> ssrjson.dumps(-(1<<63))
'-9223372036854775808'
>>> ssrjson.dumps((1<<64)-1)
'18446744073709551615'
>>> ssrjson.dumps(1<<64)
Traceback (most recent call last):
  File "<python-input>", line 1, in <module>
    ssrjson.dumps(1<<64)
    ~~~~~~~~~~~~~^^^^^^^
ssrjson.JSONEncodeError: convert value to unsigned long long failed

ssrjson.loads treats overflow integers as float objects.

>>> ssrjson.loads('-9223372036854775809')  # -(1<<63)-1
-9.223372036854776e+18
>>> ssrjson.loads('-9223372036854775808')  # -(1<<63)
-9223372036854775808
>>> ssrjson.loads('18446744073709551615')  # (1<<64)-1
18446744073709551615
>>> ssrjson.loads('18446744073709551616')  # 1<<64
1.8446744073709552e+19

Floats

For floating-point encoding, ssrJSON employs a slightly modified version of the Dragonbox algorithm. Dragonbox is a highly efficient algorithm for converting floating-point to strings, typically producing output in scientific notation. ssrJSON has partially adapted this algorithm to enhance readability by outputting a more user-friendly format when no exponent is present.

Encoding and decoding math.inf are supported. ssrjson.dumps outputs the same result as json.dumps. The input of ssrjson.loads should be "infinity" with lower or upper cases (for each character), and cannot be "inf".

>>> json.dumps(math.inf)
'Infinity'
>>> ssrjson.dumps(math.inf)
'Infinity'
>>> ssrjson.loads("[infinity, Infinity, InFiNiTy, INFINITY]")
[inf, inf, inf, inf]

The case of math.nan is similar.

>>> json.dumps(math.nan)
'NaN'
>>> ssrjson.dumps(math.nan)
'NaN'
>>> ssrjson.loads("[nan, Nan, NaN, NAN]")
[nan, nan, nan, nan]

Limitations

Please note that ssrJSON is currently in the beta stage of development.

Several commonly used features are still under development, including serialization of subclasses of str, the object_hook functionality, and error location reporting during decoding. Additionally, ssrJSON will not support encoding or decoding of third-party data structures.

The ARM64 architecture is not yet supported but will be supported in the near future.

Contributing

Contributions are welcome! Please open issues or submit pull requests for bug fixes, performance improvements, or new features. There will soon be a development documentation.

License

This project is licensed under the MIT License. Licenses of other repositories are under licenses directory.

Acknowledgments

We would like to express our gratitude to the outstanding libraries and their authors:

  • CPython
  • yyjson: ssrJSON draws extensively from yyjson’s highly optimized implementations, including the core decoding logic, the decoding of bytes objects, and the number decoding routines.
  • orjson: ssrJSON references parts of orjson’s SIMD-based ASCII string encoding and decoding algorithms, as well as the dictionary key caching mechanism. Additionally, ssrJSON utilizes orjson’s pytest framework for testing purposes.
  • Dragonbox: ssrJSON employs Dragonbox for high-performance floating-point encoding.
  • xxHash: ssrJSON leverages xxHash to efficiently compute hash values for key caching.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ssrjson-0.0.2.tar.gz (362.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ssrjson-0.0.2-cp313-cp313-win_amd64.whl (640.0 kB view details)

Uploaded CPython 3.13Windows x86-64

ssrjson-0.0.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (676.9 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

ssrjson-0.0.2-cp312-cp312-win_amd64.whl (640.0 kB view details)

Uploaded CPython 3.12Windows x86-64

ssrjson-0.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (676.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

ssrjson-0.0.2-cp311-cp311-win_amd64.whl (638.9 kB view details)

Uploaded CPython 3.11Windows x86-64

ssrjson-0.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (674.9 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

ssrjson-0.0.2-cp310-cp310-win_amd64.whl (639.0 kB view details)

Uploaded CPython 3.10Windows x86-64

ssrjson-0.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (674.9 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

ssrjson-0.0.2-cp39-cp39-win_amd64.whl (639.0 kB view details)

Uploaded CPython 3.9Windows x86-64

ssrjson-0.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (674.9 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

File details

Details for the file ssrjson-0.0.2.tar.gz.

File metadata

  • Download URL: ssrjson-0.0.2.tar.gz
  • Upload date:
  • Size: 362.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for ssrjson-0.0.2.tar.gz
Algorithm Hash digest
SHA256 75d7575de223939740b7785c01f4319f68980ba2efee25b88dea0216ac6b23bc
MD5 0321213b3f8c7ce66fe87d07e036d1fe
BLAKE2b-256 78cbe64f5ed490c494f74de447cbd7be34e526e2680892434af0e62dfedb16b0

See more details on using hashes here.

File details

Details for the file ssrjson-0.0.2-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: ssrjson-0.0.2-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 640.0 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for ssrjson-0.0.2-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 1eca3a9662b3c9d49f507986c63d467e685c89e202e08f19887c9e3d58d97a69
MD5 ccd36ed20a10e1e3321d09fb3e35babd
BLAKE2b-256 a937cfa0a1015d3f46cfab4a661c849684293a32b5ba34cddd3d06e38268a81a

See more details on using hashes here.

File details

Details for the file ssrjson-0.0.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for ssrjson-0.0.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 9266e8e7ffa73c879d652158e542f47163f76c559f6cade1b7c98f47088842c5
MD5 63539db932e62fd5a2c995388b03aa54
BLAKE2b-256 289a04db3bc705d2d15be59469e97c88d47bde7f10d025b8fefa12f851aeb666

See more details on using hashes here.

File details

Details for the file ssrjson-0.0.2-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: ssrjson-0.0.2-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 640.0 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for ssrjson-0.0.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e4f3b0038d8ec713fd644779b6eca02d7b4b1d33fc641d38a6519eac2eaabfdd
MD5 8de4247a1d58fc1082721655c4769b37
BLAKE2b-256 b85d115c02402c335e8537717a4b5ac50497f6ae7580ea4fc3599934c8892e32

See more details on using hashes here.

File details

Details for the file ssrjson-0.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ssrjson-0.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f6e5fc458ebbd52fc9b42cde35bd66d96bbcf141332b2db66e7473d48fab6b91
MD5 9892c1360082e54a810123c6a2769f0e
BLAKE2b-256 fb6d9030de7682ffd73552fafdd7404530a0e2e5d1ea44a25c9d7fb7907d3157

See more details on using hashes here.

File details

Details for the file ssrjson-0.0.2-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: ssrjson-0.0.2-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 638.9 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for ssrjson-0.0.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 b1b52b0ef28eff1c5333bccf3e8b084818adc1aa40fbdfddcd12ad376ab211d5
MD5 c5f3988134f365bee5ea8e40bb489bf8
BLAKE2b-256 9d52d25fccc3cd8e82e70d0c8f19109b4613f55495c11a4042bedf718299e483

See more details on using hashes here.

File details

Details for the file ssrjson-0.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ssrjson-0.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 83419921f971dd03da95efb688b119149139ffc8fc08b371fe93ef7f7e500b22
MD5 6714b0ab60c996febcfc0c66c92f1f43
BLAKE2b-256 4ee6d9c49a55c01e4a1345cdd7b21fd8ecd4c297c268c3880e62c1028f23c97d

See more details on using hashes here.

File details

Details for the file ssrjson-0.0.2-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: ssrjson-0.0.2-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 639.0 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for ssrjson-0.0.2-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 c680926587f519422db2574a7c7a32d4374fde36ecfdbb84ecd52ac5a1f823cc
MD5 a5060b050c6fa5cb0f6762b6e8ed313d
BLAKE2b-256 afd69d1ea62d25e7c7765fb649e9c537f73b8a6abae5e5e41ecc2b60cbdff12a

See more details on using hashes here.

File details

Details for the file ssrjson-0.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ssrjson-0.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7c95a4f5e7668851d313b16dec8e23551b39c665208d42498527bafb500c3d5b
MD5 af898c30648eb4fbf8c44deab590ad65
BLAKE2b-256 4044cdf07d7ecc3d933373a23e5eb5f3421df51b0bee36bb012709db598c364b

See more details on using hashes here.

File details

Details for the file ssrjson-0.0.2-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: ssrjson-0.0.2-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 639.0 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for ssrjson-0.0.2-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 fb65f61f6c960f5ea7d4c2a8393f30a643dc6b66706f05820b970e070695c529
MD5 1d0d696f1ffc876c4c3fe0a322e7dadc
BLAKE2b-256 af3bc798ec6649925c4c7883f5d914fbbbce7f53e92c0494af1c032df317d81c

See more details on using hashes here.

File details

Details for the file ssrjson-0.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ssrjson-0.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 cc1b2538918367fcbfca8c43339be0015220498ea5e00f8009ced4e42ff3bbaf
MD5 56781a6207571a3fec5773252f10c466
BLAKE2b-256 3c847bb449ecd28339434b8268fba249a1d9f4f03e64fb612572b93630af9550

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page