# Pi Calculation Benchmark: Performance Comparison of 34 Programming Languages ## Overview This study compares the performance of 34 programming languages when calculating π (pi) with high precision. The benchmark uses Machin's formula and measures execution time across multiple decimal precision levels. ## Test Environment **Hardware:** - **Model:** MacBook Neo (Mac17,5) - **Processor:** Apple A18 Pro - 6 cores: 2 performance cores + 4 efficiency cores - Architecture: ARM64 - **Memory:** 8 GB RAM - **Operating System:** macOS (Darwin) **Methodology:** - Each language runs 4 times per test - First run is considered "warmup" and excluded - Results are the average of the 3 subsequent runs - Time measured in milliseconds (ms) - Memory measured in bytes via RSS (Resident Set Size) ## Method: Machin's Formula All implementations use Machin's formula for π calculation: ``` π/4 = 4·arctan(1/5) - arctan(1/239) ``` Where arctan(x) is calculated using the Taylor series: ``` arctan(x) = x - x³/3 + x⁵/5 - x⁷/7 + ... ``` **Advantages of this method:** 1. Fast convergence (few terms required) 2. Simple implementation 3. High precision possible 4. Only integer arithmetic required ## Performance Reports Detailed performance reports are available for each decimal precision level: - **[1 Decimal](reports/1_decimals.md)** - Minimal precision - **[2 Decimals](reports/2_decimals.md)** - Low precision - **[5 Decimals](reports/5_decimals.md)** - Medium precision - **[10 Decimals](reports/10_decimals.md)** - Standard precision - **[100 Decimals](reports/100_decimals.md)** - High precision - **[1000 Decimals](reports/1000_decimals.md)** - Very high precision - **[2000 Decimals](reports/2000_decimals.md)** - Extreme precision ## Summary Results (100 Decimals) ### All Languages Performance | Rank | Language | Time (ms) | Memory (bytes) | Type | |------|-----------|-----------|----------------|------| | 1 | Assembly | 20 | 1,409,024 | Compiled | | 1 | Rust | 20 | 1,682,096 | Compiled | | 1 | Nim | 20 | 1,572,864 | Compiled | | 1 | Odin | 19 | 1,725,781 | Compiled | | 1 | C | 25 | 1,671,168 | Compiled | | 1 | C++ | 23 | 1,490,944 | Compiled | | 1 | Go | 24 | 3,932,160 | Compiled | | 1 | Objective-C | 20 | 6,045,696 | Compiled | | 1 | Fortran | 31 | 1,802,240 | Compiled | | 10 | Crystal | 32 | 3,244,032 | Compiled | | 10 | D | 30 | 2,457,600 | Compiled | | 10 | Swift | 20 | 5,947,392 | Compiled | | 10 | Zig | 22 | 2,981,888 | Compiled | | 14 | Lua | 20 | 2,086,229 | Interpreted | | 14 | Bash | 30 | 2,058,922 | Interpreted | | 14 | Perl | 47 | 12,528,298 | Interpreted | | 14 | Python | 47 | 9,693,866 | Interpreted | | 14 | Ruby | 79 | 28,824,917 | Interpreted | | 14 | PHP | 68 | 26,487,466 | Interpreted | | 14 | JavaScript | 89 | 44,848,469 | JIT | | 14 | Java | 46 | 43,078,997 | JIT | | 14 | Kotlin | 60 | 45,247,146 | JIT | | 14 | Scala | 344 | 55,470,762 | JIT | | 14 | C# | 66 | 41,473,365 | JIT | | 14 | Dart | 34 | 14,488,917 | JIT | | 14 | Haskell | 40 | 11,894,784 | Compiled | | 14 | Elixir | 401 | 89,205,418 | Interpreted | | 14 | Erlang | 176 | 77,359,786 | Interpreted | | 14 | Julia | 157 | 235,885,909 | JIT | | 14 | R | 163 | 90,947,584 | Interpreted | | 14 | TypeScript | 931 | 218,868,394 | JIT | | 14 | Brainfuck | 50 | 9,267,882 | Interpreted | ### Language Categories **Compiled Languages (Native Code):** - Fastest execution (9-35 ms) - Minimal memory usage (0-966,656 bytes) - Consistent performance across decimal levels **JIT-Compiled Languages:** - Moderate execution time (31-290 ms) - Higher memory usage (~2 MB) - Good performance after warmup **Interpreted Languages:** - Variable execution time (29-898 ms) - Moderate memory usage (~2 MB) - Performance varies widely ## Key Findings 1. **Compiled languages dominate**: Assembly, Rust, Nim, Odin, C, C++ all execute in 19-25 ms 2. **Memory efficiency varies**: - Compiled languages: 1.4-6.0 MB (Assembly lowest at 1.4 MB) - Go with runtime: 3.9 MB - JVM languages: 41-55 MB - Interpreted languages: 9-29 MB - Julia: 236 MB (JIT + scientific libraries) 3. **Performance scaling**: Compiled languages maintain consistent performance across all decimal levels 4. **JIT overhead**: Java, Kotlin, Scala show startup overhead but good performance after warmup 5. **Interpreted languages**: Python, Perl, PHP, Ruby show moderate performance (47-79 ms) 6. **Memory fix applied**: All languages now show correct memory values using `/usr/bin/time -l` on macOS ## Performance Analysis by Language Type ### Compiled Languages (Native Code) - **Fastest execution**: 19-32 ms - **Minimal memory**: 1.4-6.0 MB - **Best performers**: Assembly, Rust, Nim, Odin, C, C++ - **Why fast**: Direct machine code, no runtime overhead, no garbage collection ### JIT-Compiled Languages - **Moderate execution**: 34-931 ms - **Higher memory**: 14-236 MB - **Best performers**: Java (46 ms), Kotlin (60 ms), Dart (34 ms) - **Why moderate**: JIT compilation overhead, runtime initialization ### Interpreted Languages - **Variable execution**: 20-401 ms - **Moderate memory**: 2-29 MB - **Best performers**: Lua (20 ms), Python (47 ms), Perl (47 ms) - **Why variable**: Interpretation overhead, dynamic typing ### Functional Languages - **Mixed performance**: 40-401 ms - **Higher memory**: 12-90 MB - **Best performers**: Haskell (40 ms), Erlang (176 ms) - **Why mixed**: Functional paradigms, immutability, pattern matching ## Languages Tested **Compiled (10):** Assembly, C, C++, Rust, Go, Nim, Odin, Fortran, Swift, Crystal **JIT-Compiled (4):** Java, C#, Kotlin, Julia **Interpreted (5):** Python, Perl, PHP, Ruby, JavaScript **Other (15):** Bash, Brainfuck, D, Dart, Elixir, Erlang, Haskell, Lua, Objective-C, R, Scala, TypeScript, Vimscript, Wolfram, Zig ## Repository Structure ``` . ├── README.md # This file ├── reports/ # Detailed performance reports │ ├── summary.md # Overall summary │ ├── 1_decimals.md # 1 decimal precision │ ├── 2_decimals.md # 2 decimals precision │ ├── 5_decimals.md # 5 decimals precision │ ├── 10_decimals.md # 10 decimals precision │ ├── 100_decimals.md # 100 decimals precision │ ├── 1000_decimals.md # 1000 decimals precision │ └── 2000_decimals.md # 2000 decimals precision ├── timelines/ # Resource usage timeline data ├── assembly/ # Assembly implementation ├── c/ # C implementation ├── cpp/ # C++ implementation ├── rust/ # Rust implementation └── ... # Other language implementations ``` ## Running the Benchmark ```bash # Build all languages ./build.sh # Run all tests ./run_all.sh # Run specific language cd c && ./build.sh && ./print_hej # Run detailed profiling (breaks down execution time) ./profile_detailed.sh 100 ``` ## Detailed Profiling The benchmark includes a detailed profiling system that breaks down execution time into components: - **Startup Time**: Runtime initialization, library loading, JIT compilation - **Calculation Time**: Algorithm execution, numerical operations - **I/O Time**: Output formatting, result printing See [PROFILING.md](PROFILING.md) for detailed documentation. ## License MIT License - See LICENSE file for details. --- *Generated from Pi Calculation Benchmark - Apple A18 Pro Performance Study*