Rustのスライスとポインタの速度比較

どんぐらい違うのかなーって気になったので, 適当に実験した軽いメモ

1000万回回したらこんな感じ

Start!
slice_time: 0.666
pointer_time: 0.485
43175
39986

コードはこれ

変に最適化されないようにしたつもり

use std::time::Instant;
use rand::Rng;

fn main() {
    // 試行回数
    let count = 10000000;
    // バッファサイズ
    let size = 100000;

    let mut rng = rand::thread_rng();

    // 2つのバッファ用意して適当に値放り込んどく
    let mut buf1: Vec<u8> = Vec::new();
    let mut buf2: Vec<u8> = Vec::new();
    for _ in 0..size {
        buf1.push(rng.gen_range(0..255));
        buf2.push(rng.gen_range(0..255));
    }

    // スライスとポインタ用意するよ
    let slice_buf = &buf1;
    let pointer_buf = buf2.as_ptr();

    // アクセス先のindexを事前に用意
    let mut index_list: Vec<usize> = Vec::new();
    for _ in 0..count {
        index_list.push(rng.gen_range(0..size));
    }

    // アクセスした値を放り込む箱用意しとくよ
    let mut slice_result: Vec<u8> = vec![0;count];
    let mut pointer_result: Vec<u8> = vec![0;count];


    println!("Start!");

    // スライスアクセス計測
    let slice_start = Instant::now();
    for (i, index) in index_list.iter().enumerate() {
        slice_result[i] = slice_buf[*index];
    }
    let slice_end = slice_start.elapsed();
    println!("slice_time: {}.{:03}", slice_end.as_secs(), slice_end.subsec_nanos() / 1_000_000);


    // ポインタアクセス計測
    let pointer_start = Instant::now();
    for (i, index) in index_list.iter().enumerate() {
        unsafe {
            pointer_result[i] = *pointer_buf.offset(*index as isize);
        }
    }
    let pointer_end = pointer_start.elapsed();
    println!("pointer_time: {}.{:03}", pointer_end.as_secs(), pointer_end.subsec_nanos() / 1_000_000);


    // なんか処理しとかないと, 最適化で消える気がするので適当に
    println!("{}", slice_result.iter().filter(|&v| *v == 100).count());
    println!("{}", pointer_result.iter().filter(|&v| *v == 100).count());
}