[back]

2023-01-01 15:20:17 +09:00

# 雑記

## 睡眠

10時間くらい? 外出て音ゲやって疲労してたおかげで熟眠できたっぽい。寝覚めは良好

## contains()の計算時間を調べる

気になったので。環境的な差がアレだから参考値程度だと思うけど文中検索とかしたいので知っておきたかった。 とりあえず単純な例。

コード

use std::time::Instant;

fn main() {
    // 検索されるデータ
    let data = gen_data();
    // 検索するデータ
    let target_data = rand::random::<u32>();

    // 計測
    let start = Instant::now();
    let result = data.contains(&target_data);
    let end = start.elapsed();

    println!("{}", result);
    println!("{}.{:03}s", end.as_secs(), end.subsec_nanos() / 1_000_000);
}

fn gen_data() -> Vec<u32> {
    let mut result: Vec<u32> = Vec::new();
    for _ in 0..1_000_000 {
        result.push(rand::random::<u32>());
    }
    result
}

出力

false
0.028s

シンプルなデータなら.028秒/100万件くらい?以降はこれを単位時間1uとしていく。 データをもう少し複雑にしてみる。

コード

use std::time::Instant;
use rand::{Rng, rngs::ThreadRng};

fn main() {
    // 検索されるデータ
    let data = gen_complex_data();
    // 検索するデータ
    let target_data = ComplexData::get_random();

    // 計測
    let start = Instant::now();
    let result = data.contains(&target_data);
    let end = start.elapsed();

    println!("{}", result);
    println!("{}.{:03}s", end.as_secs(), end.subsec_nanos() / 1_000_000);
}

// つくるよ
fn gen_complex_data() -> Vec<ComplexData> {
    let mut result: Vec<ComplexData> = Vec::new();
    for _ in 0..1_000_000 {
        // 適当にランダム生成
        result.push(ComplexData::get_random());
    }
    result
}
...

データはこんな感じ:

// なんかデータ
#[derive(PartialEq)]
struct ComplexData {
    pub id: String,
    pub age: u32,
    pub class: Class,
}
// なんか追加の情報
#[derive(PartialEq)]
enum Class {
    Nil,
    Bronze,
    Silver,
    Gold,
    Platinum,
    Diamond,
}

出力

false
0.087s

3.1uくらい?PartialEqだから単純にデータ一種類につき1uかかる感じな気がしてきた。というか多分そうなんじゃないか 今度はString::contains()を試す。

コード

use std::time::Instant;
use rand::{distributions::Alphanumeric, Rng};

fn main() {
    // 検索される文字列
    let data = gen_string_data();
    // 検索する文字列
    let target_data = String::from("WhenShallWeThreeMeetAgain");

    // 計測
    let start = Instant::now();
    let result = data.contains(&target_data);
    let end = start.elapsed();

    println!("{}", data);
    println!("{}", result);
    println!("{}.{:03}s", end.as_secs(), end.subsec_nanos() / 1_000_000);
}

// 文字列作んべ
fn gen_string_data() -> String {
    let mut rng = rand::thread_rng();
    let result: String = (0..1_000_000)
        .map(|_| rng.sample(Alphanumeric) as char).collect(); 
    result
}

出力

false
0.000s

ハヤイ。圧倒的ハヤイだ。恐ろしい。 そういえばRustの文字列周りのメモリ処理は特別にチューニングされてるとかなんとか聞いたり聞かなかったりしたような記憶があったようなないような。これかァ…… ちなみにtarget_dataを6文字に減らして結果の表示桁数を9桁にしたらやっと0.000000001sになった、そのくらいハヤイ。ヤバイ。

結論

contains()、少なくともString::contains()は何も考えずに使ってよさそう。