Bitcode (De)Serialize is slower than RMP-Serde and Bincode 1.3.3 Serde

Updated on

DISCLAIMER: Expressed views on this blog are my own.

I assert that rmp and bincode are much faster than bitcode despite the "rust serialization benchmark". Bitcode is highly compressible as well, it claims and that I will not test.

There is this
https://david.kolo.ski/rust_serialization_benchmark/ and its comparing apples to oranges when it comes to bin code. Are you going to be reusing a bitbode buffer when typeically serializing and deserializing objects? How about using serde which most applications use. The benchmark is highly unrealistic.

This is the result I get when using multiple serialization algorithms. You can see bitcode is essentially cheating with buffer. bincode completely creams bitcode even with its cheating buffer benchmark. It's serde implementation perf is horrendous compared to the other ones who implement it. You are losing self describability with this algorithm too! RMP with struct map does a lot better.

I wouldn't use bitcode unless I plan to use it with a buffer and without serde. Extremely limited cases. If it hadn't made the claim it was BLAZING fast and pushed you to look at the serialization benchmark, i wouldn't have cared to consider it. I like RMP-Serde. It's a very very high performance implementation.

Bincode2 using a buffer with serde support is faster than bitcode with/out buffer though on par with bincode1 so it didn't improve overall. I'm just saying a bullshit benchmark is bullshit. Best bench implementations yourself and look at the bench code to see if it matches how you will use it before taking claims to heart.

Finally, rmp_serialize is what should have been benched as it has encode/decode and I'm sure it is fast as sh*t using a buffer.

Results

bitcode encode          time:   [612.53 ns 614.82 ns 618.11 ns]
change: [+0.1224% +0.6868% +1.3411%] (p = 0.02 < 0.05)
Change within noise threshold.
Found 9 outliers among 100 measurements (9.00%)
3 (3.00%) low mild
3 (3.00%) high mild
3 (3.00%) high severe

bitcode decode time: [250.37 ns 252.56 ns 254.70 ns]
change: [+2.2927% +3.1695% +3.9389%] (p = 0.00 < 0.05)
Performance has regressed.

bitcode encode buffer time: [101.91 ns 102.04 ns 102.18 ns]
Found 4 outliers among 100 measurements (4.00%)
4 (4.00%) high severe

bitcode decode buffer time: [117.39 ns 117.99 ns 118.62 ns]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild

bitcode serialize time: [973.17 ns 977.08 ns 980.77 ns]
change: [+0.8945% +1.5039% +2.1152%] (p = 0.00 < 0.05)
Change within noise threshold.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high severe

bitcode deserialize time: [726.16 ns 730.27 ns 734.33 ns]
change: [-0.1322% +0.6167% +1.3755%] (p = 0.12 > 0.05)
No change in performance detected.

rmp serialize time: [155.31 ns 157.37 ns 159.38 ns]
change: [-1.2007% -0.1032% +1.0683%] (p = 0.86 > 0.05)
No change in performance detected.

rmp deserialize time: [486.28 ns 491.97 ns 502.32 ns]
change: [+5.8874% +8.1198% +11.150%] (p = 0.00 < 0.05)
Performance has regressed.
Found 4 outliers among 100 measurements (4.00%)
1 (1.00%) low severe
2 (2.00%) low mild
1 (1.00%) high severe

bincode serialize time: [43.965 ns 43.992 ns 44.024 ns]
change: [-0.7689% -0.5473% -0.3112%] (p = 0.00 < 0.05)
Change within noise threshold.
Found 13 outliers among 100 measurements (13.00%)
8 (8.00%) high mild
5 (5.00%) high severe

bincode deserialize time: [106.13 ns 106.59 ns 107.07 ns]
change: [+1.0239% +1.4535% +1.9065%] (p = 0.00 < 0.05)
Performance has regressed.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild

rmp serialize struct map
time: [248.12 ns 249.86 ns 251.52 ns]
change: [+0.6303% +1.3242% +2.0389%] (p = 0.00 < 0.05)
Change within noise threshold.

rmp deserialize struct map
time: [557.89 ns 565.31 ns 572.36 ns]
change: [+5.6395% +6.9683% +8.2664%] (p = 0.00 < 0.05)
Performance has regressed.
Found 4 outliers among 100 measurements (4.00%)
4 (4.00%) low mild

The Struct Layout

#[derive(Default, Debug, Serialize, Deserialize, Encode, Decode)]
struct MyStruct {
    field1: u32,
    field2: String,
    field3: Option<f64>,
    #[serde(with = "serde_bytes")]
    field4: Vec<u8>,
}

Libraries

bincode = "1.3.3"
bitcode = { version = "^0", features = ["serde"]}
serde = { version = "^1.0", features = ["derive"] }
serde_bytes = "^0"
serde_with = "^1.12"
rmp = "^0"
rmp-serde = "^1"

You just read "Bitcode (De)Serialize is slower than RMP-Serde and Bincode 1.3.3 Serde". Please share if you liked it!
You can read more recent posts here.