Changelog¶
1.6.0 (unreleased)¶
1.5.0 (2026-02-25)¶
Direct PickleValue to JSON string writer (
json_writer.rs), bypassing allserde_json::Valueintermediate allocations (PG path 1.3-3.3x faster than dict +json.dumps())Direct known-type encoding for datetime, date, time, timedelta, and Decimal – writes pickle opcodes inline, skipping PickleValue intermediate
Thread-local buffer reuse for both encode and JSON writer paths
Thread-local class pickle cache per (module, name) pair – single memcpy replaces 7 opcode writes for ~99.6% of records
O(1)
@clshash lookup replaces O(n) key scan for marker detectionDirect i64 LONG1 encoding (eliminates BigInt heap allocation)
Profile-guided optimization (PGO) support with real FileStorage + synthetic data profiling (adds 5-15%)
Performance (PGO build, vs CPython pickle)¶
Encode: 1.7-9.2x faster (synthetic), 3-5x faster (real FileStorage)
Decode: 1.0-2.3x faster (synthetic), near parity on real-world data
PG JSON path: 1.4x faster at median on 1,692 real ZODB records
Full codec overhead: ~28 us per object (both directions)
1.4.0 (2026-02-24)¶
Add
decode_zodb_record_for_pg_json()– converts ZODB pickle records directly to a JSON string entirely in Rust with the GIL released, eliminating the intermediate Python dict +json.dumps()step (1.3x faster full pipeline on real-world data)Enable thin LTO (
lto = "thin") and single codegen unit (codegen-units = 1) in Cargo release profile for 6-9% faster decode/encode
1.3.0 (2026-02-24)¶
Fix SETITEMS/SETITEM/APPENDS/APPEND on dict/list subclasses (OrderedDict, defaultdict, deque, etc.) – previously crashed with
ValueError: SETITEMS on non-dict[#5]Box Instance variant as
Instance(Box<InstanceData>), reducing PickleValue enum from 56 to 48 bytes (-13% weighted benchmark improvement)
1.2.2 (2026-02-22)¶
Security review fixes (addresses #3):
CODEC-C1: Validate non-negative length in LONG4 and BINSTRING opcodes.
CODEC-C2: Cap memo size at 100,000 entries to prevent OOM via LONG_BINPUT.
CODEC-H1: Add recursion depth limit (1,000) to encoder and PyObject converter.
CODEC-H2: Pre-scan dict keys to avoid quadratic re-processing of mixed-key dicts.
CODEC-M1: Limit LONG opcode text representation to 10,000 characters.
CODEC-M2: Reject odd-length item lists in BTree bucket
format_flat_data().CODEC-M3: Cap BINUNICODE8/BINBYTES8 length at 256 MB before allocation.
1.2.1 (2026-02-17)¶
Fix shared reference data loss: update memo after BUILD [#2]
1.2.0 (2026-02-10)¶
Release GIL during pure-Rust pickle decoding phases, allowing other Python threads to run during the CPU-bound parse
Add
decode_zodb_record_for_pgfor single-pass PG optimization (combines decode + ref extraction + null-byte sanitization)
1.1.0¶
Add builds for Python 3.14
1.0.0¶
Features¶
Pickle protocol 2-3 support (ZODB standard), partial protocol 4 support
ZODB two-pickle record format with shared memo between class and state pickles
Compact JSON markers for Python types without direct JSON equivalents:
@t(tuple),@b(bytes),@set,@fset,@dt(datetime),@date,@time,@td(timedelta),@dec(Decimal),@uuid,@ref(persistent ref)Known type handlers for datetime (with full timezone support), date, time, timedelta, Decimal, UUID, set, frozenset
BTree support: flattened JSON with
@kv,@ks,@children,@first,@nextmarkersEscape hatch: unknown types safely encoded as
@pkl(base64 pickle fragment)Full roundtrip fidelity: encode to JSON and decode back produces identical pickle bytes
Direct PickleValue to PyObject conversion (bypasses serde_json intermediate layer)
Direct PyObject to pickle bytes encoder (bypasses PickleValue AST for encode)
Python 3.10-3.14 support, wheels for Linux/macOS/Windows
Performance (release build)¶
Decode: up to 1.8x faster than CPython pickle, 1.3x typical ZODB
Encode: up to 7.0x faster than CPython pickle, 4.0x typical ZODB
On real Plone 6 database (8,400+ records): 1.3x faster decode (median), 18.7x faster mean; 3.5x faster encode, 0 errors across 182 distinct types