Skip to content

Commit 5fa1b89

Browse files
committed
separate benchmarks from spec
1 parent 1550863 commit 5fa1b89

2 files changed

Lines changed: 47 additions & 44 deletions

File tree

BENCHMARKS.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Performance
2+
3+
BEVE with [Glaze](https://github.com/stephenberry/glaze) versus [JSON](https://www.json.org/), [MessagePack](https://github.com/msgpack/msgpack-c), and [CBOR](https://cbor.io/) (via [Glaze](https://github.com/stephenberry/glaze)).
4+
5+
## Speedup vs BEVE (Baseline)
6+
7+
Higher means BEVE is faster by that factor. Format: Write/Read
8+
9+
| Test | JSON | MsgPack | CBOR |
10+
|------|------|---------|------|
11+
| Complex Nested Object | 2.6x/2.2x | 2.2x/10.1x | 1.0x/1.1x |
12+
| std::vector\<double\> (10K) | 150.8x/147.6x | 17.5x/37.8x | 1.0x/1.0x |
13+
| std::vector\<float\> (10K) | 221.8x/231.6x | 33.1x/73.8x | 1.0x/1.0x |
14+
| std::vector\<uint64_t\> (10K) | 45.6x/85.5x | 17.9x/36.5x | 1.0x/1.0x |
15+
| std::vector\<uint32_t\> (10K) | 53.8x/88.8x | 34.0x/72.1x | 1.0x/1.0x |
16+
| std::vector\<uint16_t\> (10K) | 91.7x/130.8x | 67.6x/164.3x | 1.0x/0.9x |
17+
18+
> CBOR benchmarks use [RFC 8746](https://datatracker.ietf.org/doc/rfc8746/) typed arrays via Glaze.
19+
20+
[Performance test code](https://github.com/stephenberry/binary_performance)
21+
22+
## Message Sizes
23+
24+
| Test | JSON | BEVE | MessagePack | CBOR |
25+
|------|------|------|-------------|------|
26+
| Complex Nested Object | 616 B | 564 B | 545 B | 560 B |
27+
| std::vector\<double\> (10K) | 219.02 KB | 78.13 KB | 87.89 KB | 78.13 KB |
28+
| std::vector\<float\> (10K) | 124.11 KB | 39.07 KB | 48.83 KB | 39.07 KB |
29+
| std::vector\<uint64_t\> (10K) | 199.23 KB | 78.13 KB | 87.89 KB | 78.13 KB |
30+
| std::vector\<uint32_t\> (10K) | 104.97 KB | 39.07 KB | 48.83 KB | 39.07 KB |
31+
| std::vector\<uint16_t\> (10K) | 56.96 KB | 19.53 KB | 29.26 KB | 19.54 KB |
32+
33+
BEVE and CBOR (with RFC 8746 typed arrays) store contiguous arrays as raw memory blocks, achieving the same message sizes and throughput when using optimized implementations like Glaze. MessagePack encodes each element individually with type tags, resulting in larger messages and slower performance for numeric arrays.
34+
35+
## Struct Serialization: BEVE vs CBOR
36+
37+
For struct-heavy workloads, BEVE is faster than CBOR due to its little-endian wire format (no byte swaps on x86/ARM), avoiding float conversions, and easier key handling.
38+
39+
| Test | Write | Read |
40+
|------|-------|------|
41+
| Coordinate (3 doubles) | 1.25x | 1.25x |
42+
| vector\<Sensor\> (100 elements) | 1.23x | 1.36x |
43+
| NestedConfig (50 sensors + map) | 1.29x | 1.29x |
44+
| vector\<Coordinate\> (1000 elements) | 1.34x | 1.23x |
45+
46+
[Benchmark code](https://github.com/stephenberry/beve/blob/main/cpp/benchmarks/beve_cbor_benchmark.cpp)

README.md

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,50 +17,7 @@ Version 1.0
1717
1818
## Performance
1919

20-
BEVE with [Glaze](https://github.com/stephenberry/glaze) versus [JSON](https://www.json.org/), [MessagePack](https://github.com/msgpack/msgpack-c), and [CBOR](https://cbor.io/) (via [Glaze](https://github.com/stephenberry/glaze)).
21-
22-
### Speedup vs BEVE (Baseline)
23-
24-
Higher means BEVE is faster by that factor. Format: Write/Read
25-
26-
| Test | JSON | MsgPack | CBOR |
27-
|------|------|---------|------|
28-
| Complex Nested Object | 2.6x/2.2x | 2.2x/10.1x | 1.0x/1.1x |
29-
| std::vector\<double\> (10K) | 150.8x/147.6x | 17.5x/37.8x | 1.0x/1.0x |
30-
| std::vector\<float\> (10K) | 221.8x/231.6x | 33.1x/73.8x | 1.0x/1.0x |
31-
| std::vector\<uint64_t\> (10K) | 45.6x/85.5x | 17.9x/36.5x | 1.0x/1.0x |
32-
| std::vector\<uint32_t\> (10K) | 53.8x/88.8x | 34.0x/72.1x | 1.0x/1.0x |
33-
| std::vector\<uint16_t\> (10K) | 91.7x/130.8x | 67.6x/164.3x | 1.0x/0.9x |
34-
35-
> CBOR benchmarks use [RFC 8746](https://datatracker.ietf.org/doc/rfc8746/) typed arrays via Glaze.
36-
37-
[Performance test code](https://github.com/stephenberry/binary_performance)
38-
39-
### Message Sizes
40-
41-
| Test | JSON | BEVE | MessagePack | CBOR |
42-
|------|------|------|-------------|------|
43-
| Complex Nested Object | 616 B | 564 B | 545 B | 560 B |
44-
| std::vector\<double\> (10K) | 219.02 KB | 78.13 KB | 87.89 KB | 78.13 KB |
45-
| std::vector\<float\> (10K) | 124.11 KB | 39.07 KB | 48.83 KB | 39.07 KB |
46-
| std::vector\<uint64_t\> (10K) | 199.23 KB | 78.13 KB | 87.89 KB | 78.13 KB |
47-
| std::vector\<uint32_t\> (10K) | 104.97 KB | 39.07 KB | 48.83 KB | 39.07 KB |
48-
| std::vector\<uint16_t\> (10K) | 56.96 KB | 19.53 KB | 29.26 KB | 19.54 KB |
49-
50-
BEVE and CBOR (with RFC 8746 typed arrays) store contiguous arrays as raw memory blocks, achieving the same message sizes and throughput when using optimized implementations like Glaze. MessagePack encodes each element individually with type tags, resulting in larger messages and slower performance for numeric arrays.
51-
52-
### Struct Serialization: BEVE vs CBOR
53-
54-
For struct-heavy workloads, BEVE is faster than CBOR due to its little-endian wire format (no byte swaps on x86/ARM), avoiding float conversions, and easier key handling.
55-
56-
| Test | Write | Read |
57-
|------|-------|------|
58-
| Coordinate (3 doubles) | 1.25x | 1.25x |
59-
| vector\<Sensor\> (100 elements) | 1.23x | 1.36x |
60-
| NestedConfig (50 sensors + map) | 1.29x | 1.29x |
61-
| vector\<Coordinate\> (1000 elements) | 1.34x | 1.23x |
62-
63-
[Benchmark code](https://github.com/stephenberry/beve/blob/main/cpp/benchmarks/beve_cbor_benchmark.cpp)
20+
See [BENCHMARKS.md](BENCHMARKS.md) for detailed performance comparisons and message sizes.
6421

6522
## Why Tagged Messages?
6623

0 commit comments

Comments
 (0)