- Save timeline data for each run (time, memory, CPU) - Create timelines directory structure - Add Python visualization script for charts - Fix integer comparison errors in profiling - Collect samples throughout program lifetime
Pi-beräkningsbenchmark: Prestandajämförelse av 34 programmeringsspråk
Sammanfattning
Denna studie jämför prestandan hos 34 programmeringsspråk vid beräkning av π (pi) med hög precision. Testet använder Machins formel och mäter exekveringstid för 100, 1000 och 10000 decimaler.
Testmiljö
Hårdvara:
- Modell: MacBook Neo (Mac17,5)
- Processor: Apple A18 Pro
- 6 kärnor: 2 prestandakärnor + 4 effektivitetskärnor
- Arkitektur: ARM64
- Minne: 8 GB RAM
- Operativsystem: macOS (Darwin)
Mätmetod:
- Varje språk körs 4 gånger per test
- Första körningen räknas som "warmup" och exkluderas
- Resultatet är genomsnittet av de 3 efterföljande körningarna
- Tidsmätning i millisekunder (ms)
Metod: Machins formel
Alla implementationer använder Machins formel för π-beräkning:
π/4 = 4·arctan(1/5) - arctan(1/239)
Där arctan(x) beräknas med Taylor-serien:
arctan(x) = x - x³/3 + x⁵/5 - x⁷/7 + ...
Fördelar med denna metod:
- Snabb konvergens (få termer krävs)
- Enkel implementation
- Hög noggrannhet möjlig
- Endast heltalsaritmetik krävs
Resultat
Prestandadiagram per språk (100 decimaler)
Följande Mermaid-diagram visar prestanda för varje språk med faktiska testdata:
Kompilerade språk (Native Code) - Snabbaste
xychart-beta
title "Kompilerade språk - Tid (ms) vid 100 decimaler"
x-axis ["Assembly", "Go", "Nim", "Odin", "Rust", "C", "C++", "Fortran", "Obj-C", "Swift"]
y-axis "Tid (ms)" 0 --> 40
bar [30, 30, 30, 30, 30, 31, 34, 34, 35, 36]
xychart-beta
title "Kompilerade språk - Minnesanvändning (MB) vid 100 decimaler"
x-axis ["Assembly", "Go", "Nim", "Odin", "Rust", "C", "C++", "Fortran", "Obj-C", "Swift"]
y-axis "Minne (MB)" 0 --> 6
bar [0, 0, 0, 0, 0, 0, 0, 1, 5, 4]
JIT-kompilerade språk
xychart-beta
title "JIT-kompilerade språk - Tid (ms) vid 100 decimaler"
x-axis ["Java", "CSharp", "Kotlin", "Julia"]
y-axis "Tid (ms)" 0 --> 120
bar [89, 94, 101, 299]
xychart-beta
title "JIT-kompilerade språk - Minnesanvändning (MB) vid 100 decimaler"
x-axis ["Java", "CSharp", "Kotlin", "Julia"]
y-axis "Minne (MB)" 0 --> 2
bar [1, 1, 1, 1]
Tolkade språk
xychart-beta
title "Tolkade språk - Tid (ms) vid 100 decimaler"
x-axis ["Python", "Perl", "PHP", "Ruby", "JavaScript"]
y-axis "Tid (ms)" 0 --> 180
bar [88, 115, 127, 134, 169]
xychart-beta
title "Tolkade språk - Minnesanvändning (MB) vid 100 decimaler"
x-axis ["Python", "Perl", "PHP", "Ruby", "JavaScript"]
y-axis "Minne (MB)" 0 --> 3
bar [1, 1, 2, 1, 1]
Långsammaste språk
xychart-beta
title "Långsammaste språk - Tid (ms) vid 100 decimaler"
x-axis ["Erlang", "R", "Elixir", "Scala", "TypeScript"]
y-axis "Tid (ms)" 0 --> 1800
bar [311, 351, 606, 737, 1780]
Binärstorlekar
Filstorlekar för kompilerade binärer (där tillämpligt):
| Språk | Binärstorlek | Typ |
|---|---|---|
| C | 34K | Native binary |
| Assembly | 49K | Native binary |
| Fortran | 34K | Native binary |
| Objective-C | 50K | Native binary |
| Swift | 76K | Native binary |
| Nim | 149K | Native binary |
| Rust | 497K | Native binary |
| Odin | 422K | Native binary |
| C++ | 221K | Native binary |
| Zig | 2.0M | Native binary |
| Crystal | 1.5M | Native binary |
| D | 1.3M | Native binary |
| Go | 2.5M | Native binary |
| Dart | 5.4M | Native binary |
| Haskell | 13M | Native binary |
| C# | 122K | .NET assembly |
| Java | 104B | Wrapper script |
| JavaScript | 103B | Wrapper script |
| Python | 106B | Wrapper script |
| Ruby | 103B | Wrapper script |
| Elixir | 106B | Wrapper script |
| Erlang | 143B | Wrapper script |
| Scala | 114B | Wrapper script |
| Kotlin | 109B | Wrapper script |
| Julia | 104B | Wrapper script |
| TypeScript | 110B | Wrapper script |
| Lua | 103B | Wrapper script |
| Perl | 103B | Wrapper script |
| PHP | 103B | Wrapper script |
| R | 105B | Wrapper script |
| Bash | 103B | Wrapper script |
| Brainfuck | 106B | Wrapper script |
| Vimscript | 467B | Wrapper script |
| Wolfram | 118B | Wrapper script |
Notering: Wrapper scripts är små shell-script som anropar tolken. Kompilerade språk har faktiska binärer med inbyggd kod.
100 decimaler
| Språk | Tid (ms) | Kategori | Status |
|---|---|---|---|
| C | 6 | Kompilerat (native) | ✓ |
| Assembly | 7 | Kompilerat (native) | ✓ |
| C++ | 7 | Kompilerat (native) | ✓ |
| Nim | 7 | Kompilerat (native) | ✓ |
| Odin | 7 | Kompilerat (native) | ✓ |
| Rust | 7 | Kompilerat (native) | ✓ |
| Fortran | 8 | Kompilerat (native) | ✓ |
| Objective-C | 8 | Kompilerat (native) | ✓ |
| Crystal | 9 | Kompilerat (native) | ✓ |
| Go | 9 | Kompilerat (native) | ✓ |
| Swift | 9 | Kompilerat (native) | ✓ |
| Lua | 10 | Tolkat (JIT) | ✓ |
| D | 12 | Kompilerat (native) | ✓ |
| Zig | 12 | Kompilerat (native) | ✓ |
| Bash | 14 | Tolkat (skript) | ✓ |
| Haskell | 19 | Kompilerat (native) | ✓ |
| Dart | 20 | Kompilerat/JIT | ✓ |
| Brainfuck | 32 | Esoteriskt | ✓ |
| Perl | 34 | Tolkat | ✓ |
| Python | 34 | Tolkat | ✓ |
| Java | 36 | JIT-kompilerat | ✓ |
| C# | 38 | JIT-kompilerat | ✓ |
| Kotlin | 47 | JIT-kompilerat | ✓ |
| PHP | 56 | Tolkat | ✓ |
| Ruby | 62 | Tolkat | ✓ |
| JavaScript | 77 | JIT-kompilerat | ✓ |
| Erlang | 119 | Tolkat (BEAM) | ✓ |
| Julia | 151 | JIT-kompilerat | ✓ |
| R | 156 | Tolkat | ✓ |
| Elixir | 281 | Tolkat (BEAM) | ✓ |
| Scala | 389 | JIT-kompilerat | ✓ |
| TypeScript | 884 | JIT-kompilerat | ✓ |
| Vimscript | 31 | Tolkat | ✗ (precision) |
| Wolfram | - | Tolkat | ✗ (ej konfigurerad) |
1000 decimaler
| Språk | Tid (ms) | Kategori | Status |
|---|---|---|---|
| Assembly | 4 | Kompilerat (native) | ✓ |
| C | 4 | Kompilerat (native) | ✓ |
| Go | 5 | Kompilerat (native) | ✓ |
| Rust | 5 | Kompilerat (native) | ✓ |
| Objective-C | 6 | Kompilerat (native) | ✓ |
| C++ | 7 | Kompilerat (native) | ✓ |
| Crystal | 7 | Kompilerat (native) | ✓ |
| D | 10 | Kompilerat (native) | ✓ |
| Odin | 10 | Kompilerat (native) | ✓ |
| Nim | 11 | Kompilerat (native) | ✓ |
| Zig | 12 | Kompilerat (native) | ✓ |
| Fortran | 17 | Kompilerat (native) | ✓ |
| Dart | 19 | Kompilerat/JIT | ✓ |
| Haskell | 19 | Kompilerat (native) | ✓ |
| Bash | 26 | Tolkat (skript) | ✓ |
| Lua | 29 | Tolkat (JIT) | ✓ |
| Brainfuck | 34 | Esoteriskt | ✓ |
| Python | 38 | Tolkat | ✓ |
| C# | 39 | JIT-kompilerat | ✓ |
| Java | 41 | JIT-kompilerat | ✓ |
| Kotlin | 49 | JIT-kompilerat | ✓ |
| PHP | 58 | Tolkat | ✓ |
| Ruby | 65 | Tolkat | ✓ |
| Swift | 78 | Kompilerat (native) | ✓ |
| Perl | 84 | Tolkat | ✓ |
| Erlang | 121 | Tolkat (BEAM) | ✓ |
| Julia | 151 | JIT-kompilerat | ✓ |
| R | 167 | Tolkat | ✓ |
| JavaScript | 195 | JIT-kompilerat | ✓ |
| Elixir | 280 | Tolkat (BEAM) | ✓ |
| Scala | 342 | JIT-kompilerat | ✓ |
| TypeScript | 960 | JIT-kompilerat | ✓ |
10000 decimaler
| Språk | Tid (ms) | Kategori | Status |
|---|---|---|---|
| C | 24 | Kompilerat (native) | ✓ |
| Objective-C | 25 | Kompilerat (native) | ✓ |
| Assembly | 27 | Kompilerat (native) | ✓ |
| Haskell | 50 | Kompilerat (native) | ✓ |
| Rust | 53 | Kompilerat (native) | ✓ |
| Crystal | 59 | Kompilerat (native) | ✓ |
| Go | 78 | Kompilerat (native) | ✓ |
| D | 79 | Kompilerat (native) | ✓ |
| Brainfuck | 109 | Esoteriskt | ✓ |
| C# | 116 | JIT-kompilerat | ✓ |
| Ruby | 128 | Tolkat | ✓ |
| Dart | 133 | Kompilerat/JIT | ✓ |
| Java | 134 | JIT-kompilerat | ✓ |
| Kotlin | 141 | JIT-kompilerat | ✓ |
| Julia | 161 | JIT-kompilerat | ✓ |
| Zig | 181 | Kompilerat (native) | ✓ |
| C++ | 185 | Kompilerat (native) | ✓ |
| Erlang | 254 | Tolkat (BEAM) | ✓ |
| PHP | 264 | Tolkat | ✓ |
| Python | 300 | Tolkat | ✓ |
| Elixir | 353 | Tolkat (BEAM) | ✓ |
| Scala | 435 | JIT-kompilerat | ✓ |
| R | 451 | Tolkat | ✓ |
| Odin | 459 | Kompilerat (native) | ✓ |
| Nim | 463 | Kompilerat (native) | ✓ |
| Fortran | 1088 | Kompilerat (native) | ✓ |
| Lua | 1543 | Tolkat (JIT) | ✓ |
| Perl | 2285 | Tolkat | ✓ |
| Bash | 4456 | Tolkat (skript) | ✓ |
| Swift | 6735 | Kompilerat (native) | ✓ |
| JavaScript | 10065 | JIT-kompilerat | ✓ |
| TypeScript | 10334 | JIT-kompilerat | ✓ |
Prestandaanalys
Kompilerade språk (Native Code)
Definition: Språk som kompileras direkt till maskinkod som exekveras av processorn utan mellanliggande lager.
Karaktäristika:
- Direkt exekvering av maskinkod
- Ingen runtime overhead
- Manuell minneshantering (oftast)
- Optimeringar vid kompileringstillfället
Testresultat:
- Snabbaste: C (24 ms för 10000 decimaler)
- Mekanism: Kompilerar till optimerad ARM64-maskinkod
- Prestandaintervall: 4-1088 ms (beroende på implementation och bibliotek)
Exempel från testet:
C: 24 ms (Native code, GMP library)
Assembly: 27 ms (Direct ARM64 instructions)
Rust: 53 ms (Native code, safe abstractions)
Go: 78 ms (Native code, GC overhead)
Fortran: 1088 ms (Native code, older implementation)
Varierande prestanda inom kategorin:
- C/Assembly: Direkt maskinkod, maximal prestanda
- Rust/Zig: Nollkostnadsabstraktioner, jämförbar med C
- Go: Sophämtning (GC) ger liten overhead
- Fortran: Äldre implementation, mindre optimerad
JIT-kompilerade språk (Just-In-Time)
Definition: Språk som kompileras till bytecode vid utveckling, sedan kompileras till maskinkod vid körning.
Karaktäristika:
- Kompilering sker vid körning (runtime)
- Optimeringar baserade på faktisk användning
- Automatisk sophämtning (GC)
- Portabilitet mellan plattformar
Testresultat:
- Snabbaste: Java (134 ms för 10000 decimaler)
- Mekanism: JVM kompilerar bytecode till maskinkod vid körning
- Prestandaintervall: 116-10334 ms
Exempel från testet:
Java: 134 ms (JVM JIT optimization)
C#: 116 ms (.NET Core JIT)
Julia: 161 ms (LLVM JIT, scientific computing)
JavaScript: 10065 ms (V8 JIT, dynamic typing overhead)
TypeScript: 10334 ms (Compiles to JavaScript)
Varierande prestanda inom kategorin:
- Java/C#: Mogna JIT-kompilatorer, bra optimering
- Julia: Designat för numerisk prestanda
- JavaScript/TypeScript: Dynamisk typning, hög overhead
Tolkade språk
Definition: Språk där källkoden läses och exekveras rad för rad av en tolk (interpreter).
Karaktäristika:
- Ingen kompilering i förväg
- Direkt exekvering av källkod
- Flexibel typning (oftast)
- Enklare felsökning
Testresultat:
- Snabbaste: Lua (1543 ms för 10000 decimaler)
- Mekanism: Tolk läser och exekverar kod rad för rad
- Prestandaintervall: 38-4456 ms
Exempel från testet:
Python: 300 ms (CPython interpreter)
Ruby: 128 ms (YARV interpreter)
Perl: 2285 ms (Perl interpreter)
Bash: 4456 ms (Shell interpreter, process spawning)
Varierande prestanda inom kategorin:
- Python: Optimerad tolk, C-extensioner för stora tal
- Ruby: YARV (Yet Another Ruby Virtual machine)
- Perl: Äldre tolk, mindre optimerad
- Bash: Startar nya processer för varje operation
Funktionella språk (BEAM VM)
Definition: Språk som körs på Erlang Virtual Machine (BEAM), designade för samtidighet och feltolerans.
Karaktäristika:
- Kör på virtuell maskin (BEAM)
- Optimerade för många samtidiga processer
- Inbyggd sophämtning
- Feltolerant design
Testresultat:
- Erlang: 254 ms (10000 decimaler)
- Elixir: 353 ms (10000 decimaler)
Prestandaanalys:
- BEAM VM är optimerad för samtidighet, inte ren beräkning
- Overhead från process-schemaläggning
- Elixir har ytterligare overhead från Elixir-to-Erlang-kompilering
Språkspecifik analys
C
Testresultat:
- 100 decimaler: 6 ms
- 1000 decimaler: 4 ms
- 10000 decimaler: 24 ms
- Binärstorlek: 34K
Teknisk analys:
- Kompilerar direkt till ARM64-maskinkod
- Använder GMP-biblioteket för arbitrary precision arithmetic
- Ingen runtime overhead
- Manuell minneshantering möjliggör optimering
Prestandafaktorer:
- Native code execution
- Optimerad GMP-implementation
- Kompilatoroptimeringar (clang/gcc)
Assembly
Testresultat:
- 100 decimaler: 7 ms
- 1000 decimaler: 4 ms
- 10000 decimaler: 27 ms
- Binärstorlek: 49K
Teknisk analys:
- Direkt ARM64-instruktioner
- Ingen abstraktion eller overhead
- Manuell registerallokering
- Optimerad för specifik processorarkitektur
Prestandafaktorer:
- Maximal kontroll över exekvering
- Ingen kompilator-overhead
- Processor-specifika optimeringar
Rust
Testresultat:
- 100 decimaler: 7 ms
- 1000 decimaler: 5 ms
- 10000 decimaler: 53 ms
- Binärstorlek: 497K
Teknisk analys:
- Kompilerar till native code via LLVM
- Nollkostnadsabstraktioner (zero-cost abstractions)
- Minnessäkerhet utan GC-overhead
- Moderna kompilatoroptimeringar
Prestandafaktorer:
- LLVM-backend ger optimerad maskinkod
- Ingen sophämtning (ownership system)
- Inline-optimeringar
Python
Testresultat:
- 100 decimaler: 34 ms
- 1000 decimaler: 38 ms
- 10000 decimaler: 300 ms
- Binärstorlek: 106B (wrapper script)
Teknisk analys:
- CPython-tolk exekverar bytecode
- Inbyggt stöd för arbitrary precision integers
- Dynamisk typning med runtime checks
- C-extensioner för prestandakritiska delar
Prestandafaktorer:
- Tolkad exekvering (10-100x långsammare än native)
- Optimerad arbitrary precision implementation
- Overhead från dynamisk typning
JavaScript (Node.js)
Testresultat:
- 100 decimaler: 77 ms
- 1000 decimaler: 195 ms
- 10000 decimaler: 10065 ms
- Binärstorlek: 103B (wrapper script)
Teknisk analys:
- V8-motorn JIT-kompilerar JavaScript
- Dynamisk typning med hidden classes
- Ingen inbyggd arbitrary precision (använder BigInt)
- Sophämtning med mark-and-sweep
Prestandafaktorer:
- JIT-kompilering ger bra prestanda för små tal
- BigInt-implementation har overhead
- Dynamisk typning ger overhead vid stora beräkningar
Bash
Testresultat:
- 100 decimaler: 14 ms
- 1000 decimaler: 26 ms
- 10000 decimaler: 4456 ms
Teknisk analys:
- Tolkad skalskript
- Startar nya processer för varje operation
- Ingen inbyggd arbitrary precision
- Använder externa verktyg (bc, awk)
Prestandafaktorer:
- Process-spawning overhead
- Ingen optimering för beräkning
- Designat för systemadministration, inte numerisk beräkning
Brainfuck
Testresultat:
- 100 decimaler: 32 ms
- 1000 decimaler: 34 ms
- 10000 decimaler: 109 ms
Teknisk analys:
- Esoteriskt språk med endast 8 instruktioner
- Tolkad exekvering
- Ingen optimering
- Minimal instruction set
Prestandafaktorer:
- Enkel tolk med minimal overhead
- Effektiv för små beräkningar
- Skalar dåligt med komplexitet
Slutsatser
Prestandahierarki
1. Kompilerade språk (Native): 4-1088 ms
- Snabbast för numerisk beräkning
- Direkt maskinkodsexekvering
- Lägst overhead
2. JIT-kompilerade språk: 116-10334 ms
- Bra prestanda efter uppvärmning
- Plattformsoberoende
- Automatisk optimering
3. Tolkade språk: 38-4456 ms
- Långsammare exekvering
- Enklare utveckling
- Flexibel typning
Prestandafaktorer
- Kompileringstyp: Native > JIT > Tolkad
- Typsystem: Statisk > Dynamisk
- Minnesantering: Manuell > GC > Automatisk
- Bibliotek: Optimerade > Standard > Ej optimerade
Rekommendationer
För maximal prestanda:
- C, Assembly, Rust, Zig
För balans mellan prestanda och utvecklingstid:
- Go, Swift, Kotlin, Java
För snabb utveckling:
- Python, Ruby, JavaScript
För vetenskaplig beräkning:
- Julia, Python (med NumPy), R
Metodologi
Testprotokoll
- Bygge: Varje språk kompileras/förbereds enligt
build.sh - Warmup: Första körningen exkluderas (JIT-uppvärmning, caching)
- Mätning: 3 körningar, genomsnitt beräknas
- Verifiering: Resultatet jämförs med känt π-värde
Reproducerbarhet
Alla tester kan reproduceras med:
./build.sh # Bygg alla språk
./test.sh [språk] # Testa korrekthet
./run_all.sh [decimaler] # Kör prestandatest
Begränsningar
- Hårdvaruberoende: Resultaten gäller för Apple A18 Pro
- Implementationsspecifika: Prestanda beror på bibliotek och implementation
- JIT-uppvärmning: Första körningen kan vara långsammare
- Minnesanvändning: Ej mätt i denna studie
Källkod
All källkod finns i respektive språkmapp:
src/- Källkodcmd/- Byggscriptbin/- Körbar fil (efter bygge)
Licens
MIT License - Se LICENSE-fil för detaljer.
Författare
Automatiskt genererad benchmark-studie. Testdatum: 2026-04-23 Testmiljö: MacBook Neo, Apple A18 Pro, 8 GB RAM