Rust vs Go vs C på Apple Silicon og Linux — benchmarks på rigtig hardware (2026)

Fire benchmarks på to maskiner — Apple M1 Pro (macOS/clang) og Intel i5-13400F (Linux/gcc). Rust ≈ C på M1; på x86 Linux er Rust 1,5× langsommere end gcc på rekursiv fib og Go er 2,9× langsommere. Go's matrixmultiplikationsgab er 4,7× på Linux (mod 3,3× på arm64). Overraskelsen: Rust's parallel sum på x86 er 2,8× hurtigere end C pthreads — LLVM folder sandsynligvis rækken til en lukket formel.

Kort fortalt — Fire benchmarks på to maskiner: Apple M1 Pro (arm64, macOS 26.6, clang 21) og Intel i5-13400F (x86_64, Ubuntu 24.04, gcc 13). På M1 matcher Rust C inden for støj på alle tests. På Linux x86 slår gcc rustc på rekursiv fib (1,5×) og Go’s fib falder til 2,9× langsommere end C — et meget større gab end på arm64. Den største overraskelse: Rust’s parallel sum er 2,8× hurtigere end C pthreads på x86, sandsynligvis fordi LLVM folder heltalsrækken til en lukket formel som løkken aldrig rent faktisk kører.

Opsætning

M1 Pro (arm64)i5-13400F (x86_64)
MaskineApple MacBook ProDesktop-PC
RAM16 GB125 GB
OSmacOS 26.6 (Sequoia)Ubuntu 24.04
C-compilerApple clang 21.0, -O3 -march=nativeGCC 13.3, -O3 -march=native
Go1.26.4 darwin/arm641.22.4 linux/amd64
Rust1.96.01.96.0
Rust-flag-C opt-level=3 -C target-cpu=native-C opt-level=3 -C target-cpu=native

Hvert benchmark kørtes tre gange; tabellerne nedenfor viser medianen af kørsel 2–3.

De fire benchmarks

1 — Primtalssold (primtal op til 10.000.000)

Fladt bool-array-sold: skrive-tungt sekventiel hukommelsesadgang, letgrebet indre løkke. God proxy for hukommelsesbåndbredde-begrænset kode.

2 — Rekursiv Fibonacci (n = 47)

Ingen heap-allokering, ingen løkker — ~2,97 milliarder stakrammer. Måler rå kald-dispatch, grenforudsigelse og hvor aggressivt hver compiler inliner/optimerer dyb rekursion.

3 — Matrixmultiplikation (512 × 512, f64, i-k-j løkkerækkefølge)

Cache-venlig løkkerækkefølge men stadig en tæt FP-akkumulering i den indre løkke. Her betyder auto-vektorisering og eliminering af grænsecheck mest.

4 — Parallel sum (100.000.000 heltal, 8 tråde)

8 POSIX-tråde (C), goroutines (Go) eller std::thread (Rust), der hver summerer en partition af 0..100_000_000. Tester tråd-spawn-overhead og hvor smart hver compiler håndterer den indre sum.

Resultater: Apple M1 Pro (arm64, clang 21, macOS)

BenchmarkCGo 1.26Rust 1.96
Sold (10M primtal)13,3 ms19,3 ms12,3 ms
Fib(47) rekursiv8,86 s9,84 s8,91 s
Matrixmultiplikation 512²24,7 ms80,2 ms24,1 ms
Parallel sum 100M3,0 ms10,7 ms3,4 ms

Resultater: Intel i5-13400F (x86_64, gcc 13, Linux)

BenchmarkCGo 1.22Rust 1.96
Sold (10M primtal)25,7 ms34,3 ms27,6 ms
Fib(47) rekursiv4,06 s11,86 s6,02 s
Matrixmultiplikation 512²22,5 ms106,7 ms28,3 ms
Parallel sum 100M3,4 ms8,7 ms1,2 ms

Median af 3 kørsler, kørsel 2 brugt. 2026-06-22.

Hastighed relativt til C, begge maskiner

BenchmarkGo/C (M1)Go/C (i5)Rust/C (M1)Rust/C (i5)
Sold1,45×1,33×0,92×1,07×
Fib(47)1,11×2,92×1,01×1,48×
Matrixmultiplikation3,24×4,74×0,98×1,26×
Parallel sum3,57×2,56×1,13×0,35×

Tre ting der er værd at forklare

1 — Go’s fib kollapser på x86

På M1 var Go’s fib(47) 11% langsommere end C — i praksis det samme. På i5’en er det 2,9× langsommere. Samme Go-version, samme algoritme. Forskellen er compiler-backend’en: Go’s arm64-kodegeneration håndterer dybe rekursive kaldkæder mere effektivt end dens amd64-kodegeneration. Dette er et kendt kvalitetsgab; Go’s x86-backend er generelt mindre moden end arm64-backendet til rekursionstunge mønstre.

2 — gcc slår rustc på rekursiv fib

På M1 (clang mod rustc, begge bruger LLVM) tog fib ~8,9s i begge sprog — identisk. På Linux producerede gcc 4,06s mens rustc producerede 6,02s — gcc er 1,5× hurtigere. GCC’s optimizer anvender mere aggressiv tail-rekursion og inlining-heuristikker for dette specifikke mønster på x86. Det er en påmindelse om at “Rust bruger LLVM” ikke betyder at det altid vinder over gcc; GCC har 30+ år af x86-optimeringskunst bag sig.

3 — Rust’s parallel sum er 2,8× hurtigere end C på x86

Rust-trådens krop er (start..end).sum::<u64>(). LLVM genkender en sum af en sammenhængende heltalsrækkevidde som en aritmetisk rækkeformel og erstatter løkken med en lukket beregning n*(n+1)/2 — O(1), uanset rækkeviddens størrelse. GCC med den manuelle for (i = start; i < end; i++) s += i;-løkke anvender SIMD-vektorisering men laver ikke spring til lukket form. Resultat: Rust’s otte tråde udfører hver én multiplikation; C’s otte tråde summerer hver 12,5M heltal. 2,8×-forskellen er udelukkende en compiler-optimeringsforkel, ikke en sprogforskel. (På arm64 var denne effekt mindre fordi Apple clang også anvender noget af denne optimering.)

Binærstørrelse og kompileringstid

C (macOS)C (Linux)Go (macOS)Go (Linux)Rust (macOS)Rust (Linux)
Binærstørrelse (sold)33 KB16 KB2,5 MB1,9 MB431 KB4,3 MB
Kold kompilering (sold)96 ms54 ms319 ms193 ms660 ms134 ms

Rust-binæren der er 4,3 MB på Linux mod 431 KB på macOS er den mest slående størrelsesforkel. På macOS linker Rust mod system-dylibs for dele af standardbiblioteket og holder binæren lille. På Linux linker Rust alt statisk, hvilket producerer en større men fuldt selvstændig binær uden system-biblioteksafhængighed — en reel fordel til containere.

Kompileringstider vender: Rust er 134ms på Linux mod 660ms på macOS for en enkelt fil. LLVM’s x86_64-backend er markant hurtigere til at udsende kode end dens arm64-backend.

Anno 2026: hvor lever hvert sprog?

C er stadig referencepunktet og stadig hurtigst på rå rekursivt arbejde når gcc’s optimizer er involveret. I 2026 er det ikke et førstehåndsvalg til nye projekter medmindre du skriver kernekode, embedded firmware eller FFI-klister — men compiler-kunsten akkumuleret siden 1972 er reel.

Go ramte 1.0 i 2012 med en klar tese: gør det at skrive netværkstjenester lige så hurtigt at udvikle som Python, mens man kører med effektiviteten af et kompileret sprog. Det har i høj grad lykkedes. Hvad det betaler for det: GC’en tilføjer latensvarians, og performance-loftet er lavere end Rust eller C for beregningstunge løkker. fib-resultatet på x86 afslører også at Go’s optimizer har reelle kvalitetsgab på visse mønstre — den er tunet til hvad Go-kode faktisk ligner (interfaces, kanaler, HTTP-handlere), ikke trærekursion.

Rust ramte 1.0 i 2015 og har brugt et årti på at bevise at hukommelsessikkerhed uden GC er opnåeligt i stor skala. I 2026 accepterer Linux-kernen Rust til drivere (siden 6.1), Firefox og Chromium erstatter gradvist C++ med det, og ISRG omskriver kritisk netværksinfrastruktur i det. Den lukkede formel-sum-optimering ovenfor er et godt eksempel på hvad “zero-cost abstractions” betyder i praksis: at skrive idiomatisk Rust lader compileren anvende transformationer som en manuel C-løkke ikke kan udløse.

Pick-one-guide

Du vil…Vælg
Skrive en Linux-driver eller kernemodulC (eller Rust hvis subsystemet accepterer det)
Bygge en mikrotjeneste eller CLI-værktøj hurtigtGo — tooling + goroutines + hurtig iteration
Skrive sikkerhedskritisk systemkodeRust — borrowchecker, ingen GC, ingen UB
Optimere en varm numerisk indre løkkeC eller Rust — SIMD, ingen grænsecheck, fuld LLVM
Levere en statisk binær til en containerGo (statisk som standard) eller Rust (musl)
Målrette arm64-performanceRust ≈ C, bedre end Go
Målrette x86-rekursiv kodeC med gcc vinder; Rust konkurrencedygtig; Go halter

Benchmarks kørt på personligt hardware; dine tal vil variere med CPU, OS-indstillinger og compiler-flag. Koden er fire enkelt-fils programmer, ingen eksterne afhængigheder. Alle compilere kaldt med fulde optimeringsflag som vist ovenfor.