LoginSignup
9
2

More than 1 year has passed since last update.

Rust で書いたプログラムがなんか遅い

Posted at

要約

C++ だと 11.44 秒かかるものが Rust だと 18.36 秒もかかって遅い。なぜだ?

議論する内容

Leibniz 級数というものを使って円周率を計算するプログラムを Rust と C++ で実装して速度を比較する。実行時に級数の項の数を引数として渡して計算させる。うまくプログラムが書けていれば、Rust と C++/Clang ではほとんど性能が変わらないはずだが…

Rust でのコード・コンパイル・実行

leibniz.rs
use std::env;

fn powersign(n: i64) -> i64 {
    if n % 2 == 0 {
        1
    } else {
        -1
    }
}

fn leibniz(n: i64) -> f64 {
    let mut s: f64 = 0.0;
    for k in 0..=n {
        s += powersign(k) as f64/ (2 * k + 1) as f64;
    }
    4.0 * s
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let n = &args[1].parse::<i64>().unwrap();
    println!("{}", leibniz(*n));
}

コンパイル:

$ rustc -C opt-level=3 -o leibniz-rust leibniz.rs

実行:

$ time ./leibniz-rust 10000000000
3.141592653688346

________________________________________________________
Executed in   19.24 secs    fish           external
   usr time   18.36 secs    0.16 millis   18.36 secs
   sys time    0.04 secs    1.74 millis    0.04 secs

C++ での実装・コンパイル・実行

leibniz.cpp
#include <cstdint>
#include <sstream>
#include <iostream>
#include <limits>

template <typename T>
auto is_even(T n) {
    return n % T{2} == T{0};
}

template <typename T>
auto powersign(T n) {
    return is_even(n) ? T{1} : T{-1};
}

template <typename T>
auto leibniz(T n) {
	using F = double;
    auto s = F{0};
    for (auto k = T{0}; k <= n; k++) {
        s += static_cast<F>(powersign(k)) / static_cast<F>(T{2} * k + T{1});
    }
    return F{4} * s;
}

int main(int, char * argv[]) {
    std::stringstream stream;
    stream << argv[1];
    int64_t n;
    stream >> n;

    typedef std::numeric_limits<double> lim;
    std::cout.precision(lim::max_digits10);
    std::cout << leibniz(n) << std::endl;
}

コンパイル:

$ clang++ -O3 -o leibniz-c++ leibniz.cpp

実行:

$ time ./leibniz-c++ 10000000000
3.1415926536883458

________________________________________________________
Executed in   11.50 secs    fish           external
   usr time   11.44 secs    0.11 millis   11.44 secs
   sys time    0.03 secs    1.02 millis    0.03 secs

考察

C++ で実装し Clang-15.0.7 でコンパイルしたものだと 11.44 秒かかるものが Rust/rustc-1.67.1 だと 18.36 秒もかかる。遅すぎる。

昔(数年前)、同様のコードで速度差をテストしたときは、差異はほとんどなかったはずなのに、なぜなのだろうか。コンパイラが悪くなってしまったのだろうか。なぜ Rust のコードが遅いのかわかる方がいらっしゃったら教えて下さい。

9
2
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
2