π Multi-language benchmark suite comparing serial vs parallel algorithm implementations in C, C++, Go, Java, Python, and Rust.
A comprehensive benchmarking suite that implements and compares the performance of classic algorithms across multiple programming languages. The project features:
- π Three classic algorithms: Fibonacci, Prime Numbers, and QuickSort
- β‘ Both serial and parallel implementations for each algorithm
- π Performance benchmarking and comparison across 6 languages
- π Visualization tools for analyzing results
- π οΈ Configurable thread/processor count for parallel tests
- β¨ Consistent code formatting and linting across all languages
This project implements three algorithmic tests (Fibonacci sequence, prime number calculation, and QuickSort) in both serial and parallel versions across multiple programming languages.
multilang-algo-bench/
βββ bin/ # Compiled executables
βββ logs/ # Benchmark results in JSON format
βββ src/ # Source code organized by language
β βββ c/ # C implementation
β βββ cpp/ # C++ implementation
β βββ go/ # Go implementation
β βββ java/ # Java implementation
β βββ python/ # Python implementation
β βββ rust/ # Rust implementation
βββ benchmark_results.png # Visualization of benchmark results
βββ json.jar # JSON library for Java
βββ process_logs.py # Script to process and visualize results
βββ .clang-format # C/C++ formatting rules
βββ .flake8 # Python linting configuration
βββ checkstyle.xml # Java style checking rules
βββ pyproject.toml # Python black formatter config
βββ rustfmt.toml # Rust formatting rules
βββ README.md # This file
- C: GCC or compatible C compiler with pthread support
- C++: A modern C++ compiler (C++17 or later)
- Go: Go 1.14 or later
- Python: Python 3.6 or later with pandas
- Rust: Rust 1.31 or later (needs Cargo)
- Java: JDK 8 or later with org.json library
For Rust, you'll need these dependencies (already in Cargo.toml):
[dependencies]
rayon = "1.7"
rand = "0.8"
serde_json = "1.0"
num_cpus = "1.0"For Python, install required packages:
pip install pandasFor Java:
- org.json library (provided as json.jar)
- checkstyle for code quality
When running on a cluster or HPC environment, you may need to load the appropriate modules:
# For Rust
module load Rust/1.65.0 # or another available version
# For Java
module load Java/11.0.2 # or Java/13.0.2 or higher
# For Go
module load Go # load appropriate Go module if availableC:
gcc -O3 src/c/c_test.c -o bin/c_test -pthread -lmC++:
g++ -O3 -std=c++17 src/cpp/cpp_test.cpp -o bin/cpp_test -pthreadGo:
cd src/go
go build -o ../../bin/go_test benchmark.goRust:
cd src/rust
cargo build --release
cp target/release/speed_comparison ../../bin/rust_testJava:
# For Java 11 or higher
javac -cp json.jar src/java/JavaTest.java -d bin
# For Java 8 (if needed for compatibility)
javac -source 1.8 -target 1.8 -cp json.jar src/java/JavaTest.java -d binPython:
# Python scripts are run directly from sourceAll implementations support configuring the number of processors/threads via command line argument. If not specified, they will use all available processors.
C:
bin/c_test [num_threads]C++:
bin/cpp_test [num_threads]Go:
bin/go_test [num_processors]Rust:
bin/rust_test [num_threads]Java:
cd bin
java -cp .:../json.jar JavaTest [num_processors]Python:
python3 src/python/python_test.py [num_processors]-
Fibonacci Sequence:
- Serial: Dynamic programming implementation
- Parallel: Chunk-based calculation with configurable thread count
- Test size: First 35 numbers in sequence
-
Prime Numbers:
- Serial: Simple trial division
- Parallel: Distributed workload across threads
- Test size: Numbers up to 100,000
-
QuickSort:
- Serial: Classic recursive implementation
- Parallel: Multi-threaded with depth control
- Test size: 1,000,000 random integers
After running the tests, each implementation will create a JSON log file in the logs directory. To analyze and visualize the results, run:
python3 process_logs.pyThis will:
- Read all benchmark results from the logs directory
- Generate comparative statistics for all three tests
- Display thread/processor count used by each implementation
- Segmentation Faults in C: The C implementation has improved memory management and thread synchronization to prevent segmentation faults.
- Path Issues: All implementations now handle paths properly, ensuring results are written to the correct logs directory regardless of where the executable is run from.
- Java Compatibility: For older Java versions (8), compile with
-source 1.8 -target 1.8flags. - Go Path Issues: If you encounter "module not found" errors in Go, ensure you're using the correct path structure or update the go.mod file.
- Rust Parallel Functions: The Rust fibonacci_parallel function has been optimized to handle array bounds properly when working with chunks.
- The parallel versions utilize:
- C: POSIX threads (pthreads) for multi-threading
- C++: std::async and futures for task parallelism
- Go: goroutines and channels for concurrent execution
- Python: multiprocessing for parallel processing
- Rust: rayon for parallel iterators and join patterns
- Java: Fork/Join framework and parallel streams
- Fibonacci calculation is fastest in Rust, C, and C++ for serial execution.
- Prime number calculation shows excellent parallel speedup in Go, C++, and Python.
- QuickSort sees significant speedup in C++, Python, and Java when running in parallel.
- The overhead of parallelization makes the parallel Fibonacci implementation slower than the serial version in most languages due to the small workload.
Below are the performance ratios relative to Python (Python = 1.0, higher numbers mean faster performance):
| Language | Fibonacci | Prime Numbers | QuickSort |
|---|---|---|---|
| Rust | 663.32x | 9.09x | 33.26x |
| C++ | 678.26x | 10.18x | 33.23x |
| C | 903.62x | 10.62x | 35.55x |
| Go | 480.39x | 5.81x | 7.31x |
| Java | 140.80x | 3.90x | 27.82x |
| Python | 1.00x | 1.00x | 1.00x |
| Language | Fibonacci | Prime Numbers | QuickSort |
|---|---|---|---|
| Rust | 2162.34x | 21.14x | 16.63x |
| C++ | 1339.81x | 40.94x | 47.59x |
| C | 1977.34x | 24.23x | 23.22x |
| Go | 5044.14x | 12.29x | 4.76x |
| Java | 220.00x | 2.13x | 41.01x |
| Python | 1.00x | 1.00x | 1.00x |
Key observations:
- In serial implementations, C shows exceptional performance for Fibonacci (903.62x faster than Python)
- C++ excels at QuickSort in parallel implementation (47.59x faster than Python)
- For prime numbers, C++ leads in both serial (10.18x) and parallel (40.94x) performance
- Go shows the best parallel Fibonacci performance (5044.14x faster than Python)
- Java maintains strong QuickSort performance in parallel implementation (41.01x faster than Python)
Note: Higher numbers indicate better performance relative to Python. Values are automatically extracted from the performance_ratio.json file.