Why is Rust n-body benchmark slower than C++?

According to n-body benchmark Rust is more than 2 times slower here than C++ and C. Why is that? It looks like it is very math-heavy code where Rust should excel and compile to mostly same code.

Is it problem of code or Rust lacks some optimizations?

http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=rust&id=1

1 Like

A couple of thoughts looking at the code, the C++ version does not have to 'match' inside the loop, and is using vectorised operators.

Does rust have vector operators, that compile to SIMD instructions? Even if Rust had auto-vectorization it cannot get near the performance of direct vector operations.

There's a faster SIMD version of n-body as an example in the simd crate.

1 Like

why is it not submitted yet?

I'm guessing because the benchmarks aren't exactly well-maintained. The project is using a Makefile for building rather than using cargo, which makes it harder to make contributions. The written code is also in bad form (lots of clippy warnings)

It requires unstable code (i.e. one must use a nightly compiler), while I believe the website sensibly uses only stable.

4 Likes

n-body Rust #2 program

14.600s rustc 1.7.0
24.533s rustc 1.8.0

?

Yes, that's some serious performance degradation. Perhaps someone should look into it.

I would open a ticket for this.

just wanted to say, i tried it myself and got very different numbers.

on the website it says

  • C++: 9.30
  • rust: 24.07
  • Go: 21.73

i just copy/pasted the source-code and ran it on my vm:

rustc 1.13.0-nightly (1576de0ce 2016-08-21)
go version go1.7 linux/amd64
building C++: ..
building rust: cargo build --release
    Finished release [optimized] target(s) in 0.0 secs
building go: go build -o nbody-go
running C++: time ./nbody.gpp-3.gpp_run 50000000
-0.169075164
-0.169059907

real    0m5.197s
user    0m5.196s
sys     0m0.000s
running rust: time target/release/shootout-nbody 50000000
-0.169075164
-0.169059907

real    0m7.000s
user    0m6.996s
sys     0m0.000s
running go: time ./nbody-go 50000000
-0.169075164
-0.169059907

real    0m9.206s
user    0m9.224s
sys     0m0.004s
1 Like

See also the n-body code here:

2 Likes

this is really nice to learn, thank you!

i tried your code and got this:

running 50000000x
----------------------------------------- versions
g++ (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rustc 1.13.0-nightly (1576de0ce 2016-08-21)
go version go1.7 linux/amd64
----------------------------------------- rust-1
http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=rust&id=1
-0.169075164
-0.169059907

real    0m6.902s
user    0m6.896s
sys     0m0.004s
----------------------------------------- rust-2
http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=rust&id=2
-0.169075164
-0.169059907

real    0m6.897s
user    0m6.892s
sys     0m0.000s
----------------------------------------- rust-3
https://internals.rust-lang.org/t/loop-unrolling-on-request/3091
-0.169075164
-0.169059907

real    0m6.416s
user    0m6.404s
sys     0m0.004s
----------------------------------------- rust-4
https://internals.rust-lang.org/t/loop-unrolling-on-request/3091
-0.169075164
-0.169059907

real    0m5.032s
user    0m5.008s
sys     0m0.020s
----------------------------------------- go-1
http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=go&id=1
-0.169075164
-0.169059907

real    0m8.958s
user    0m8.988s
sys     0m0.000s
----------------------------------------- C++-3
http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=gpp&id=3
-0.169075164
-0.169059907

real    0m5.163s
user    0m5.160s
sys     0m0.000s
1 Like