Skip to content

Instantly share code, notes, and snippets.

@juancarlospaco
Last active October 20, 2022 21:05
Show Gist options
  • Save juancarlospaco/79ef9064c51af11b6d2e93dc35a4f9c0 to your computer and use it in GitHub Desktop.
Save juancarlospaco/79ef9064c51af11b6d2e93dc35a4f9c0 to your computer and use it in GitHub Desktop.
Rust vs C++ vs C vs Cython vs Nim. (year 2022)

Build

$ ./compileall.sh 

# Cleanout #############################################################
# Go ###################################################################

real    0m0,283s
user    0m0,227s
sys     0m0,064s
# Nim ##################################################################

real    0m0,500s
user    0m0,504s
sys     0m0,030s
# C ####################################################################

real    0m0,075s
user    0m0,065s
sys     0m0,015s
# C++ ##################################################################

real    0m0,679s
user    0m0,601s
sys     0m0,078s
# Cython3 C ############################################################

real    0m0,533s
user    0m0,492s
sys     0m0,040s

real    0m0,624s
user    0m0,554s
sys     0m0,070s
# Cython3 C++ ##########################################################

real    0m0,497s
user    0m0,487s
sys     0m0,010s

real    0m1,015s
user    0m0,932s
sys     0m0,081s
# Rust #################################################################

real    0m0,460s
user    0m0,320s
sys     0m0,075s
# Line counts ##########################################################
7 yes.c
9 yes.cpp
5 yes.rs
7 yes.nim
6 yes.pyx
7 yes.go
# Filesizes ############################################################
24K     yes_c
44K     yes_cpp
8,8M    yes_rust
52K     yes_nim
40K     yes_cyc
40K     yes_cycpp
1,2M    yes_go
# LDD yes_nim ###########################################################
        linux-vdso.so.1 (0x00007ffeb10e1000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007fc89f063000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fc89f287000)
# LDD yes_c #############################################################
        linux-vdso.so.1 (0x00007ffcdddfe000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f50587c3000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f50589df000)
# LDD yes_cpp ###########################################################
        linux-vdso.so.1 (0x00007fff69d94000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f458c717000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007f458c62f000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f458c60f000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f458c428000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f458c983000)
# LDD yes_cyc ############################################################
        linux-vdso.so.1 (0x00007ffe553fb000)
        libpython3.10.so.1.0 => /usr/lib/libpython3.10.so.1.0 (0x00007f0392875000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f039268e000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007f03925a6000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f0392c62000)
# LDD yes_cycpp ############################################################
        linux-vdso.so.1 (0x00007ffc5a7ca000)
        libpython3.10.so.1.0 => /usr/lib/libpython3.10.so.1.0 (0x00007fb324b27000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fb3248f0000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007fb324808000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fb3247e8000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007fb324601000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fb324f14000)
# LDD yes_rust ##########################################################
        linux-vdso.so.1 (0x00007ffe31765000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f718f9d2000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f718f7eb000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f718fa70000)
# LDD yes_go ############################################################
        not a dynamic executable

$

Bench

$ ./yes_c     | pv -r > /dev/null
$ ./yes_cpp   | pv -r > /dev/null
$ ./yes_cyc   | pv -r > /dev/null
$ ./yes_cycpp | pv -r > /dev/null
$ ./yes_rust  | pv -r > /dev/null
$ ./yes_go    | pv -r > /dev/null
$ ./yes_nim   | pv -r > /dev/null

Results

Lang Speed
Nim 180MiB/s
C 80MiB/s
Cython3 C 6MiB/s
Cython3 C++ 6MiB/s
C++ 5,5MiB/s
Rust 5MiB/s
Go 3MiB/s
  • Rust slow to compile, slow to run, big binaries.
  • Go slow to run, big binaries.
  • C still faster than C++.
  • Rust similar speed to C++.
  • Cython is faster than Go.

Notes

  • No Macros, no emit inline ASM directly, no call-to-C, because not all langs have it.
echo "# Cleanout #############################################################"
rm yes_nim
rm yes_c
rm yes_cpp
rm yes_cyc
rm yes_cycpp
rm yes_rust
rm yes_go
echo "# Go ###################################################################"
time go build -o yes_go -ldflags "-s -w" yes.go
echo "# Nim ##################################################################"
time nim c -d:danger --mm:arc --threads:off --verbosity:0 --passC:"-march=native" -o:yes_nim yes.nim
echo "# C ####################################################################"
time gcc -O3 -march=native -g yes.c -o yes_c
echo "# C++ ##################################################################"
time g++ -std=gnu++20 -O3 -march=native -g yes.cpp -o yes_cpp
echo "# Cython3 C ############################################################"
time cython3 -3 --embed --no-docstrings -o yes_temp.c yes.pyx
time gcc -O3 -march=native -I /usr/include/python3.10 -lpython3.10 -o yes_cyc yes_temp.c # EDITME
rm yes_temp.c
echo "# Cython3 C++ ##########################################################"
time cython3 -3 --cplus --embed --no-docstrings -o yes_temp.cpp yes.pyx
time g++ -O3 -march=native -I /usr/include/python3.10 -lpython3.10 -o yes_cycpp yes_temp.cpp # EDITME
rm yes_temp.cpp
echo "# Rust #################################################################"
time rustc -C opt-level=3 -C target-cpu=native -o yes_rust yes.rs
echo "# Line counts ##########################################################"
wc --lines yes.c
wc --lines yes.cpp
wc --lines yes.rs
wc --lines yes.nim
wc --lines yes.pyx
wc --lines yes.go
echo "# Filesizes ############################################################"
du -h yes_c
du -h yes_cpp
du -h yes_rust
du -h yes_nim
du -h yes_cyc
du -h yes_cycpp
du -h yes_go
echo "# LDD yes_nim ###########################################################"
ldd yes_nim
echo "# LDD yes_c #############################################################"
ldd yes_c
echo "# LDD yes_cpp ###########################################################"
ldd yes_cpp
echo "# LDD yes_cyc ############################################################"
ldd yes_cyc
echo "# LDD yes_cycpp ############################################################"
ldd yes_cycpp
echo "# LDD yes_rust ##########################################################"
ldd yes_rust
echo "# LDD yes_go ############################################################"
ldd yes_go
#include <stdio.h>
int main(const char* argc, const char* argv) {
while (true) {
printf("y\n");
}
}
#include <iostream>
using namespace std;
int main() {
while (true) {
cout << 'y' << endl;
}
}
package main
import "fmt"
func main() {
for {
fmt.Println("y")
}
}
proc main() =
while true:
stdout.write 'y'
stdout.write '\n'
when isMainModule:
main()
def main():
while True:
print("y")
if __name__ in "__main__":
main()
fn main() {
loop {
println!("y");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment