Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

728 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cyscale

Build Status Latest Version Supported Python versions License

Cython-accelerated SCALE codec library for Substrate-based blockchains (Polkadot, Kusama, Bittensor, etc.), with no external runtime dependencies.

A drop-in replacement for py-scale-codec: same scalecodec module name and public API, but compiled with Cython for improved throughput.

Installation

pip install cyscale

Performance

Benchmarked on Apple M-series (Python 3.13) against py-scale-codec 1.2.12. All timings are µs per call; speedup = py ÷ cy.

Primitives and small types

Benchmark py (µs) cy (µs) speedup
u8 decode 3.01 1.69 1.78×
u16 decode 2.99 1.80 1.66×
u32 decode 3.11 1.83 1.70×
u64 decode 3.09 1.79 1.73×
u128 decode 2.91 1.84 1.58×
Compact decode 9.59 6.90 1.39×
bool decode 2.93 1.61 1.82×
H256 decode 2.93 1.66 1.76×
AccountId decode (SS58 format 42) 11.45 4.31 2.66×
Str decode 12.89 8.58 1.50×
(u32, u64, bool) decode 21.96 8.36 2.63×
u32 encode 2.34 1.50 1.57×
u64 encode 2.33 1.55 1.50×
Compact encode 8.85 6.36 1.39×
H256 encode 2.47 1.42 1.74×

Large payloads

Benchmark py (µs) cy (µs) speedup
Vec decode (64 elements) 224.20 20.88 10.74×
Vec decode (1,024 elements) 3217.32 147.21 21.85×
Vec decode (16,384 elements) 50396.95 2150.86 23.43×
Bytes decode (1 KB) 14.67 9.99 1.47×
Bytes decode (64 KB) 64.15 63.30 1.01×
Bytes decode (512 KB) 379.99 429.74 0.88×
Vec decode (5 events, V10) 301.10 131.81 2.28×
MetadataVersioned decode (V10, 85 KB) 64958.83 35936.30 1.81×
MetadataVersioned decode (V13, 219 KB) 143029.99 81044.60 1.76×
MetadataVersioned decode (V14, 300 KB) 390902.34 185823.12 2.10×
Bittensor metadata + portable registry (254 KB) 443089.47 211343.83 2.10×

Primitives and small types see ~2.0–2.6× speedup. Large metadata decoding sees ~2.1–2.3× speedup — the gain compounds across thousands of recursive decode calls. Raw bulk byte operations (Bytes/Vec<u8>) above ~64 KB are dominated by memcpy and see a reduced ~1.3–1.4× speedup.

AccountId with SS58 encoding shows a 1.87× speedup — the SS58 encoding itself (ss58_encode) is pure Python and limits gains in that path.

batch_decode (cyscale-only API)

batch_decode(type_strings, bytes_list) amortises Python dispatch overhead across a list of decodes. The baseline below is a py-scale-codec decode loop, which is the equivalent operation without this API. Note: bt_decode is excluded from this comparison because it does not perform SS58 encoding — including it without that post-processing step would be unfair.

Benchmark py loop (µs) cy batch (µs) speedup
batch_decode AccountId ×10 116.66 19.36 6.03×
batch_decode AccountId ×100 1159.47 190.19 6.10×
batch_decode AccountId ×1,000 11530.59 1888.99 6.10×
Mixed (AccountId/u32/u128) ×100 599.73 71.42 8.40×

To reproduce, run:

# save a py-scale-codec baseline
python benchmarks/bench.py --save-baseline benchmarks/baseline_py.json

# compare against cy-scale-codec
PYTHONPATH=. python benchmarks/bench.py --compare benchmarks/baseline_py.json

Examples of different types

Type Description Example SCALE decoding value SCALE encoded value
bool Boolean values are encoded using the least significant bit of a single byte. True 0x01
u16 Basic integers are encoded using a fixed-width little-endian (LE) format. 42 0x2a00
Compact A "compact" or general integer encoding is sufficient for encoding large integers (up to 2**536) and is more efficient at encoding most values than the fixed-width version. 1 0x04
Vec A collection of same-typed values is encoded, prefixed with a compact encoding of the number of items, followed by each item's encoding concatenated in turn. [4, 8, 15, 16, 23, 42] 0x18040008000f00100017002a00
str, Bytes Strings are Vectors of bytes (Vec<u8>) containing a valid UTF8 sequence. "Test" 0x1054657374
AccountId An SS58 formatted representation of an account. "5GDyPHLVHcQYPTWfygtPYeogQjyZy7J9fsi4brPhgEFq4pcv" 0xb80269ec...
Enum A fixed number of variants, each mutually exclusive. Encoded as the first byte identifying the index of the variant. {'Int': 8} 0x002a
Struct For structures, values are named but that is irrelevant for the encoding (only order matters). {"votes": [...], "id": 4} 0x04b80269...

License

Apache 2.0 — see LICENSE and NOTICE.

Releases

Packages

Used by

Contributors

Languages