LoginSignup
17
7

More than 5 years have passed since last update.

Rustで乱数生成するときの処理速度の違い

Last updated at Posted at 2017-09-21

Rustで乱数を生成するときに rand クレイトを使用しますが、無意識に rand::thread_rng()を使ってしまったりします。

暗号の強度より処理速度を優先したい場合、他の乱数生成アルゴリズムを使うと良い場面があります。
そこでrandクレイトで使えるアルゴリズムの処理速度を比較してみました。

前提条件

$ system_profiler -detailLevel mini | grep "Hardware Overview" -n12 | tail -n15
123-Hardware:
124-
125:    Hardware Overview:
126-
127-      Model Name: MacBook Pro
128-      Model Identifier: MacBookPro12,1
129-      Processor Name: Intel Core i5
130-      Processor Speed: 2.7 GHz
131-      Number of Processors: 1
132-      Total Number of Cores: 2
133-      L2 Cache (per Core): 256 KB
134-      L3 Cache: 3 MB
135-      Memory: 16 GB
136-      Boot ROM Version: MBP121.0167.B33
137-      SMC Version (system): 2.28f7

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.6
BuildVersion:   16G29

$ rustc --version
rustc 1.22.0-nightly (01c65cb15 2017-09-20)

ベンチマーク結果

結論から言うと、処理速度を優先したい場合はrand::XorShiftRngを使うのがよいようです。

test bench_rng_chacha       ... bench:          31 ns/iter (+/- 2)
test bench_rng_isaac        ... bench:          16 ns/iter (+/- 3)
test bench_rng_isaac64      ... bench:           7 ns/iter (+/- 0)
test bench_rng_osrng        ... bench:       1,119 ns/iter (+/- 110)
test bench_rng_random       ... bench:          55 ns/iter (+/- 5)
test bench_rng_std          ... bench:           7 ns/iter (+/- 0)
test bench_rng_thread_rng   ... bench:          48 ns/iter (+/- 3)
test bench_rng_xorshift     ... bench:           5 ns/iter (+/- 1)

ベンチマークのソースコード

#![feature(test)]

extern crate test;
extern crate rand;

use test::Bencher;
use rand::{random, thread_rng, Rng, XorShiftRng, ChaChaRng, IsaacRng, Isaac64Rng, OsRng, StdRng};

#[bench]
fn bench_rng_random(b: &mut Bencher) {
    b.iter(|| {
        random::<f64>()
    });
}

#[bench]
fn bench_rng_thread_rng(b: &mut Bencher) {
    let mut rng = thread_rng();
    b.iter(|| {
        rng.gen_range(0., 1.)
    });
}

#[bench]
fn bench_rng_xorshift(b: &mut Bencher) {
    let mut rng = XorShiftRng::new_unseeded();
    b.iter(|| {
        rng.gen_range(0., 1.)
    });
}

#[bench]
fn bench_rng_chacha(b: &mut Bencher) {
    let mut rng = ChaChaRng::new_unseeded();
    b.iter(|| {
        rng.gen_range(0., 1.)
    });
}

#[bench]
fn bench_rng_isaac(b: &mut Bencher) {
    let mut rng = IsaacRng::new_unseeded();
    b.iter(|| {
        rng.gen_range(0., 1.)
    });
}

#[bench]
fn bench_rng_isaac64(b: &mut Bencher) {
    let mut rng = Isaac64Rng::new_unseeded();
    b.iter(|| {
        rng.gen_range(0., 1.)
    });
}

#[bench]
fn bench_rng_osrng(b: &mut Bencher) {
    let mut rng = OsRng::new().expect("OsRng::new() error.");
    b.iter(|| {
        rng.gen_range(0., 1.)
    });
}

#[bench]
fn bench_rng_std(b: &mut Bencher) {
    let mut rng = StdRng::new().expect("StdRng::new() error.");
    b.iter(|| {
        rng.gen_range(0., 1.)
    });
}

リファレンス

17
7
1

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
17
7