Rustを勉強しているため、前回の記事では、Javascript実装したものをRustで再実装してみました。
コード
main.rs
extern crate rand;
use std::env;
use rand::Rng;
struct Point {
x: f64,
y: f64
}
fn main() {
let sample: u64 = env::args().nth(1)
.expect("Usage: main SAMPLE")
.parse::<u64>().ok()
.expect("SAMPLE must be u64");
let mut inner_points: u64 = 0;
let mut rng = rand::thread_rng();
for _ in 1..sample {
let point: Point = Point { x: rng.gen::<f64>(), y: rng.gen::<f64>() };
let distance: f64 = (point.x.powi(2) + point.y.powi(2)).sqrt();
if distance < 1 as f64 {
inner_points += 1;
}
}
let pi: f64 = 4 as f64 * inner_points as f64 / sample as f64;
println!("{}", pi);
}
実験
サンプル数を10^3
から10^11
まで試しました。
$ time ./target/release/main 1000
3.18
$ time ./target/release/main 10000
3.1492
$ time ./target/release/main 100000
3.14576
$ time ./target/release/main 1000000
3.139368
$ time ./target/release/main 10000000
3.1404616
$ time ./target/release/main 100000000
3.14174324
...
考察
前回の記事のJavascript実装を、コンパイル言語とインタープリタ言語の実行時間の比較のための再利用しました。time
命令を利用して時間を計測しました。掲載時間はusr + sys
です。また、main.rs
のコンパイル時間は、rand
やlibc
などのコンパイル時間も含み3.75s
でした。
Sample | Javascript (s) | Rust (s) | Ratio (Javascript / Rust) |
---|---|---|---|
10^3 | 0.068 | 0.004 | 17.0 |
10^4 | 0.074 | 0.005 | 14.8 |
10^5 | 0.083 | 0.017 | 4.882352941 |
10^6 | 0.159 | 0.090 | 1.766666667 |
10^7 | 1.377 | 0.849 | 1.621908127 |
10^8 | 13.517 | 8.649 | 1.562839635 |
10^9 | 147.012 | 83.308 | 1.764680463 |
10^10 | 1908.46 | 864.523 | 2.20752947 |
10^11 | 26568.773 | 14148.49 | 1.877852195 |
Ratio
を見ると全て1
以上なので、Rust(コンパイル言語)の実行時間はやはり短いという割と当たり前のことが確認できました。もちろんコンパイル時間を考慮すれば、Javascript(インタープリタ言語)のほうがサンプル数が10^7
以下の場合は短いです。 サンプル数を増やしていけばRatio
が粗いながらも収束していくように少しみえます。勘違いでしょうけれど。