Rustを試してみましたよ

#なぜRust
RustはC並みに早いということですので、試してみました。
個人的にはC並みに早いというのは疑わしいというのが本音です。
どの程度迫れるのか試してみようという試みです。

#動作環境
- raspberryPi 4B+ 4G
- Ubuntu 20.04 LTS (Focal Fossa)

#はじめ方
[Rust](https://www.rust-lang.org/ja)の公式HPから作業を進めます。

curlでインストーラ（？）を取得します。

```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

インストールに伴い、パスに$HOME/.cargo/binが追加されます。
インストール直後は反映されていませんので、反映させます。

```
$ . ~/.profile
$ cargo --version
cargo 1.44.0 (05d080faa 2020-05-06)
```

#プロジェクトの作成

プロジェクトを作成します。
今回はモンテカルロ法による円周率の計算プログラムになります。

```
$ cargo new montecarlo
$ cd montecarlo
$ cargo run
   Compiling monte v0.1.0 (/home/ubuntu/test/rust/montecarlo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.73s
     Running `target/debug/monte`
Hello, world!
```

"Hello, world!"のソースは最初から入っています

#ソース

それはさておき、本論のプログラムです。

```Rust:montecarlo/Cargo.tomi
[package]
name = "montecarlo"
version = "0.1.0"
authors = ["ubuntu"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rand = "0.6"
floating-duration="0.1.2"
```

```Rust:montecarlo/src/main.rs
fn main() {

    use rand::Rng;                  // 乱数用
    use std::time::Instant;         // 時刻取得用
    use floating_duration::TimeAsFloat; // 時刻→floatへの変換用

    println!("Hello, world!");

    let loop_max = 10000000;        // 打点の回数
    let test_max = 100;             // 平均を出すためのループ

    let mut x: f32;
    let mut y: f32;

    let mut rng = rand::thread_rng();//randseedの設定

    let mut split_time: f32 = 0.0;
    for _test_count in 1..test_max {
        println!("times:{:?}", _test_count );
        let start_time = Instant::now();

        let mut count = 0;
        for _loot_count in 1..loop_max {
            x = rng.gen_range(0., 1.);  //乱数0.0~1.0
            y = rng.gen_range(0., 1.);

            if x * x + y * y <= 1.0 {
                count = count + 1;
            }

        }
        println!("pi:{}", 4.0 * count as f32 / loop_max as f32); // as f32は型キャスト
        let end_time = start_time.elapsed().as_fractional_secs();// 時刻を秒に変換
        println!("time:{:?}", end_time );

        split_time = split_time + end_time as f32

    }

    println!("AVE:{}", split_time / test_max as f32);

}
```

実行します。

```
$ cargo run
```

実行すると足りないライブラリが自動的にダウンロードされます。
ダウンロードされたライブラリはmontecarlo/target/debugに入ります。
環境には優しいような気がしますが、本番環境がセキュリティに厳しく外につながっていないのであれば非常に困りますね。

```Rust:
   Compiling rand_core v0.4.2
   Compiling autocfg v0.1.7
   Compiling libc v0.2.71
   Compiling floating-duration v0.1.2
   Compiling rand_core v0.3.1
   Compiling rand_jitter v0.1.4
   Compiling rand_isaac v0.1.1
   Compiling rand_hc v0.1.0
   Compiling rand_xorshift v0.1.1
   Compiling rand_chacha v0.1.1
   Compiling rand_pcg v0.1.2
   Compiling rand v0.6.5
   Compiling rand_os v0.1.3
    Building [==================================================>      ] 20/22: rand                          
```

続けて実行されます。

```
Hello, world!
times:1
pi:3.1414633
time:16.488487876
times:2
pi:3.1410964
time:16.490830576
```

あれ？早くないじゃん・・・

ちなみにC言語で同様の処理も作成していまして、そちらは1秒程度で処理されます。
「C言語並みに早い。」という評判は一体・・？

気が付いているかとも思いますが、debugがあるということはreleaseがあるということです。

というわけで、気を取り直して

```
$ cargo run --release
(省略)
Hello, world!
times:1
pi:3.1410291
time:0.507707403
times:2
pi:3.1419127
time:0.507432741
```

0.5秒は正直びっくりです。

#2020年6月28日追記
疑似乱数生成器をXoshiroにすることでさらに高速化することが分かりました。
詳細は拙著[モンテカルロ法による各言語の速度比較](https://qiita.com/kurooolong/items/2c95ac40a0c051c5a6ae)をご参照ください。