This benchmark compares serialization/deserialization performance between Apache Fory and Protocol Buffers in C++.
Note: Protobuf is fetched automatically via CMake FetchContent, so no manual installation is required.
| Key | Value |
|---|---|
| OS | Darwin 24.5.0 |
| Machine | arm64 |
| Processor | arm |
| CPU Cores (Physical) | 12 |
| CPU Cores (Logical) | 12 |
| Total RAM (GB) | 48.0 |
| Datatype | Operation | Fory TPS | Protobuf TPS | Faster |
|---|---|---|---|---|
| Mediacontent | Serialize | 2,312,522 | 501,867 | Fory (4.6x) |
| Mediacontent | Deserialize | 769,157 | 398,960 | Fory (1.9x) |
| Sample | Serialize | 5,046,250 | 3,182,176 | Fory (1.6x) |
| Sample | Deserialize | 941,637 | 721,614 | Fory (1.3x) |
| Struct | Serialize | 21,424,386 | 6,024,856 | Fory (3.6x) |
| Struct | Deserialize | 7,904,533 | 6,515,853 | Fory (1.2x) |
Run the complete benchmark pipeline (build, run, generate report):
cd benchmarks/cpp_benchmark ./run.sh
cd benchmarks/cpp_benchmark mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release .. cmake --build . -j$(nproc)
./fory_benchmark
# Run only Struct benchmarks ./fory_benchmark --benchmark_filter="Struct" # Run only Fory benchmarks ./fory_benchmark --benchmark_filter="Fory" # Run only serialization benchmarks ./fory_benchmark --benchmark_filter="Serialize"
# JSON output ./fory_benchmark --benchmark_format=json --benchmark_out=results.json # CSV output ./fory_benchmark --benchmark_format=csv --benchmark_out=results.csv
| Benchmark | Description |
|---|---|
BM_Fory_Struct_Serialize | Serialize a simple struct with 8 int32 fields using Fory |
BM_Protobuf_Struct_Serialize | Serialize the same struct using Protobuf |
BM_Fory_Struct_Deserialize | Deserialize a simple struct using Fory |
BM_Protobuf_Struct_Deserialize | Deserialize the same struct using Protobuf |
BM_Fory_Sample_Serialize | Serialize a complex object with various types and arrays using Fory |
BM_Protobuf_Sample_Serialize | Serialize the same object using Protobuf |
BM_Fory_Sample_Deserialize | Deserialize a complex object using Fory |
BM_Protobuf_Sample_Deserialize | Deserialize the same object using Protobuf |
BM_Fory_MediaContent_Serialize | Serialize a complex object with Media and Images using Fory |
BM_Protobuf_MediaContent_Serialize | Serialize the same object using Protobuf |
BM_Fory_MediaContent_Deserialize | Deserialize a complex object with Media and Images using Fory |
BM_Protobuf_MediaContent_Deserialize | Deserialize the same object using Protobuf |
BM_PrintSerializedSizes | Just compares the serialization sizes of Fory and Protobuf |
A simple structure with 8 int32 fields, useful for measuring baseline serialization overhead.
A complex structure containing:
Contains one Media and multiple Images.
The benchmark uses benchmarks/proto/bench.proto which is shared with the Java benchmark for consistency.
A Python script is provided to generate visual reports from benchmark results.
pip install matplotlib numpy psutil
# Run benchmark and save JSON output cd build ./fory_benchmark --benchmark_format=json --benchmark_out=benchmark_results.json # Generate report cd .. python benchmark_report.py --json-file build/benchmark_results.json --output-dir report
The script will generate:
REPORT.md) with detailed resultspython benchmark_report.py --help Options: --json-file Benchmark JSON output file (default: benchmark_results.json) --output-dir Output directory for plots and report --plot-prefix Image path prefix in Markdown report
Use profile.sh to generate flamegraphs for performance analysis:
# Profile all benchmarks ./profile.sh # Profile specific benchmarks ./profile.sh --data struct --serializer fory # Profile with custom duration ./profile.sh --serializer fory --duration 10
./profile.sh --help Options: --filter <pattern> Custom benchmark filter (regex pattern) --data <struct|sample> Filter benchmark by data type --serializer <fory|protobuf> Filter benchmark by serializer --duration <seconds> Profiling duration (default: 5) --output-dir <dir> Output directory (default: profile_output)
Example with custom filter:
# Profile a specific benchmark ./profile.sh --filter BM_Fory_Struct_Serialize
The script automatically detects and uses available tools (in order of preference):
cargo install samplyWhen using perf on Linux, the script automatically generates flamegraph SVG files. FlameGraph tools are auto-installed to ~/FlameGraph if not found.
Output files are saved to profile_output/:
perf_<timestamp>.data - Raw perf dataflamegraph_<timestamp>.svg - Interactive flamegraph visualizationOpen the SVG file in a browser to explore the flamegraph interactively.