Apich-Organization/bincode
Bincode-next: The next official rust implementation of bincode
Bincode-Next
Bincode-Next is a high-performance binary encoder/decoder pair that uses a zero-fluff encoding scheme. It is a modernized fork of the original bincode library, maintained by the Apich Organization to ensure continued development and extreme performance optimizations for the Rust ecosystem.
The size of the encoded object will be the same or smaller than the size that the object takes up in memory in a running Rust program.
Key Features
- Performance: Leverages SIMD (SSE2 on x86_64, NEON on AArch64) for rapid varint scanning and bulk primitive copying for massive throughput.
- Zero-Copy: Nested Zero-copy support via Relative Pointers and Const Alignment. (optional feature, using the
zerocopyfeature to enable) - Bit-Packing: Bit-level Packing for Space-Optimized Serialization. (optional, using the
BitPackedderive macro with theconfig::standard().with_bit_packing()config to enable) - Schema Fingerprinting: Schema Fingerprinting for Safe Versioning. (optional, using the
config::standard().with_fingerprint()with the derive macroFingerprintto enable) - Compile-time Memory Bound Validation: Compile-time Memory Bound Validation via Const Generics. (optional feature, enable the
static-sizefeature to use it) - Stream Support: Works seamlessly with
std::io(Reader/Writer) andno_stdenvironments.
Getting Started
Add bincode-next to your Cargo.toml:
[dependencies]
bincode-next = "3.0.0-rc.5"Basic Example
use bincode_next::{config, Decode, Encode};
#[derive(Encode, Decode, PartialEq, Debug)]
struct Entity {
x: f32,
y: f32,
}
#[derive(Encode, Decode, PartialEq, Debug)]
struct World(Vec<Entity>);
fn main() {
let config = config::standard();
let world = World(vec![Entity { x: 0.0, y: 4.0 }, Entity { x: 10.0, y: 20.5 }]);
// Encode to a Vec<u8>
let encoded: Vec<u8> = bincode_next::encode_to_vec(&world, config).unwrap();
// Decode from a slice
let (decoded, len): (World, usize) = bincode_next::decode_from_slice(&encoded[..], config).unwrap();
assert_eq!(world, decoded);
assert_eq!(len, encoded.len());
}Bit-Packing Example
Enable bit-packing in your configuration to use bit-level field sizing:
use bincode_next::{config, BitPacked};
#[derive(BitPacked, PartialEq, Debug)]
struct Packed {
#[bincode(bits = 3)]
a: u8,
#[bincode(bits = 5)]
b: u8,
}
fn main() {
let config = config::standard().with_bit_packing();
let val = Packed { a: 7, b: 31 };
let encoded = bincode_next::encode_to_vec(&val, config).unwrap();
// 'a' (3 bits) + 'b' (5 bits) = 8 bits (1 byte)
assert_eq!(encoded.len(), 1);
}Performance Optimizations
Bincode-Next includes advanced optimizations for extreme performance:
- SIMD Varint Scanning: Accelerates decoding of collections (like
Vec<u64>) by scanning for small values using SSE2 or NEON instructions. - Bulk Native Copy: Automatically detects when data can be copied directly from memory (e.g., slices of primitives with matching endianness) to avoid element-wise processing.
- Uninitialized Memory: Utilizes
MaybeUninitandset_lenoptimizations forVecdecoding to avoid redundant zero-initialization.
git clone https://github.com/Apich-Organization/bincode.git
cd bincode
# We need root permission and use nightly compiler to ensure the most accurate result
sudo cargo +nightly bench --bench extreme_perf
sudo cargo +nightly bench --bench complexTL;DR:Please visit https://bincode-next.apich.org/ for more detailed information.
Performance Comparison: Decoding
Baseline: bincode-next (traits, varint) at 16.878 µs
| Rank | Implementation | Interface | Int Encoding | Median Time | Relative Speed |
|---|---|---|---|---|---|
| 1 | bincode-next | traits | varint | 16.878 µs | 1.00x |
| 2 | bincode-next | traits | fixed | 21.872 µs | 1.30x |
| 3 | bincode-v2 | serde | fixed | 21.973 µs | 1.30x |
| 4 | bincode-v1 | serde | N/A | 22.074 µs | 1.31x |
| 5 | bincode-v2 | serde | varint | 25.727 µs | 1.52x |
Performance Comparison: Encoding
Baseline: bincode-next (traits, fixed) at 2.9350 µs
| Rank | Implementation | Interface | Int Encoding | Median Time | Relative Speed |
|---|---|---|---|---|---|
| 1 | bincode-next | traits | fixed | 2.9350 µs | 1.00x |
| 2 | bincode-v1 | serde | N/A | 3.0767 µs | 1.05x |
| 3 | bincode-v2 | serde | fixed | 3.3295 µs | 1.13x |
| 4 | bincode-next | traits | varint | 3.3467 µs | 1.14x |
| 5 | bincode-v2 | serde | varint | 4.2489 µs | 1.45x |
Efficiency Score: Combined Round-Trip Performance
Sum of Median Decode + Median Encode (Normalized to the fastest = 1.00x)
| Rank | Implementation | Interface | Int Encoding | Total Time | Efficiency Score |
|---|---|---|---|---|---|
| 1 | bincode-next | traits | varint | 20.225 µs | 1.00x |
| 2 | bincode-next | traits | fixed | 24.807 µs | 1.23x |
| 3 | bincode-v1 | serde | N/A | 25.151 µs | 1.24x |
| 4 | bincode-v2 | serde | fixed | 25.303 µs | 1.25x |
| 5 | bincode-v2 | serde | varint | 29.976 µs | 1.48x |
Vector u64 Decoding: Varint Performance
Contrasting small vs. large integer varint decoding.
| Dataset | Implementation | Median Time | Relative Speed |
|---|---|---|---|
| Small Varint | bincode-next (current) | 2.8256 µs | 1.00x |
| Small Varint | bincode-v2 (original) | 12.450 µs | 4.41x |
| Large Varint | bincode-next (current) | 13.062 µs | 1.00x |
| Large Varint | bincode-v2 (original) | 17.635 µs | 1.35x |
Vector u64 Decoding: Fixed Performance
Baseline: bincode-next (current) at 1.8373 µs
| Rank | Implementation | Median Time | Relative Speed |
|---|---|---|---|
| 1 | bincode-next (current) | 1.8373 µs | 1.00x |
| 2 | bincode-v1 | 7.5378 µs | 4.10x |
| 3 | bincode-v2 (original) | 10.129 µs | 5.51x |
Bulk u8 Decoding: Throughput Performance
Baseline: bincode-next (current) at 160.44 ns
| Rank | Implementation | Median Time | Relative Speed |
|---|---|---|---|
| 1 | bincode-next (current) | 160.44 ns | 1.00x |
| 2 | bincode-v2 (original) | 273.86 ns | 1.71x |
| 3 | bincode-v1 | 6307.00 ns | 39.31x |
About Security and Code Quality
For security issues, please visit the Security Team Homepage for more details on reporting.
All code tests passed miri and all main crate source code passed clippy without errors.
MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri test --all-features --no-fail-fast
cargo clippy --all-featuresWe remain committed to code security and welcomed security reporting.
And please notice that contributors shall follow the community guide lines of bincode-next.
Specification
The formal wire-format specification is available in docs/spec.md.
FAQ
Why Bincode-Next?
Bincode-Next was created to continue the legacy of the original Bincode project while pushing the boundaries of what's possible with modern Rust performance techniques and AI-assisted development.
Is it compatible with Bincode 1.x / 2.x?
Yes, Bincode-Next is designed to be wire-compatible with Bincode 2.x when using the same configurations. It also supports legacy 1.x formats via configuration.
Contributing
We welcome contributions! Please see CONTRIBUTING.md for more details.
License
Bincode-Next is licensed under either of:
- The MIT License (MIT)
- The Apache License, Version 2.0
See LICENSE.md for details.