Skip to content

thewhaleking/cyscale

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

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

A drop-in replacement for py-scale-codec — same scalecodec module name, same public API, 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.16 2.60×
u16 decode 2.99 1.25 2.40×
u32 decode 3.11 1.26 2.47×
u64 decode 3.09 1.22 2.53×
u128 decode 2.91 1.22 2.39×
Compact decode 9.59 4.38 2.19×
bool decode 2.93 1.18 2.48×
H256 decode 2.93 1.21 2.41×
AccountId decode (SS58 format 42) 11.45 6.11 1.87×
Str decode 12.89 5.82 2.22×
(u32, u64, bool) decode 21.96 5.59 3.93×
u32 encode 2.34 1.10 2.13×
u64 encode 2.33 1.20 1.93×
Compact encode 8.85 4.42 2.00×
H256 encode 2.47 1.01 2.44×

Large payloads

Benchmark py (µs) cy (µs) speedup
Vec decode (64 elements) 224.20 98.13 2.28×
Vec decode (1,024 elements) 3217.32 1423.46 2.26×
Vec decode (16,384 elements) 50396.95 22435.45 2.25×
Bytes decode (1 KB) 14.67 6.87 2.14×
Bytes decode (64 KB) 64.15 45.05 1.42×
Bytes decode (512 KB) 379.99 300.14 1.27×
Vec decode (5 events, V10) 301.10 135.32 2.23×
MetadataVersioned decode (V10, 85 KB) 64958.83 29839.68 2.18×
MetadataVersioned decode (V13, 219 KB) 143029.99 65651.69 2.18×
MetadataVersioned decode (V14, 300 KB) 390902.34 183644.98 2.13×
Bittensor metadata + portable registry (254 KB) 443089.47 212345.78 2.09×

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 42.07 2.77×
batch_decode AccountId ×100 1159.47 415.44 2.79×
batch_decode AccountId ×1,000 11530.59 4112.27 2.80×
Mixed (AccountId/u32/u128) ×100 599.73 147.75 4.06×

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.

About

Cython SCALE-Codec

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors