Sibainu Relax Room

愛犬の柴犬とともに過ごす部屋

RUST でクイックソート 2

ぼくのお友達来ないかなと探している柴犬です。

前回からの改良

GO 以上の速度を期待していたのですが、Python と同等でしたので次のように改良しました。

データの整形

データを表示するために {:?} としなければいけませんでした。

なにか余分なものが付加されているのでここを綺麗にする方法を模索しました。

その中で分かったことは、lines.enumerate() で分離するということです。

結果、 {} で綺麗な表示ができました。

前回コード(改良は run() のみ)

fn run() -> Result<(), Box<dyn Error>> {
    let path = "./input.csv";
    let buf = fs::read(path).unwrap();
    let (dec, _, _) = SHIFT_JIS.decode(&buf);
    let text = dec.into_owned();
    let lines = text.lines();

    let mut elements = Vec::new();
    // ここを改良
    for s in lines {
        let mut crec = Vec::new();
        crec.push(s.split(",").clone().nth(0));
        crec.push(s.split(",").clone().nth(1));
        elements.push(crec);
    }

    let right = elements.len();

    quicksort(&mut elements, 0, right - 1);

    for mut i in 0..50 {
        // ここを改良
        println!("{:?}/{:?}", elements[i][0], elements[i][1]);
    }

    Ok(())
}

改良後のコード

copy

fn run() -> Result<(), Box<dyn Error>> {
    let path = "./input.csv";
    let buf = fs::read(path).unwrap();
    let (dec, _, _) = SHIFT_JIS.decode(&buf);
    let text = dec.into_owned();
    let lines = text.lines();

    let mut elements = Vec::new();
    // ここを改良
    for (i, s) in lines.enumerate() {
        // i == 0 || を削除しました。(今回、見出しがないため)
        if s.trim().len() == 0 {
            continue; 
        }

        let fields: Vec<_> = s
            .split(",")
            .map(|field| field.trim())
            .collect();
        elements.push(fields);
    }

    let right = elements.len();

    quicksort(&mut elements, 0, right - 1);

    for i in 0..50 {
        // ここを改良
        println!("{},{}", elements[i][0], elements[i][1]);
    }

    Ok(())
}

コードの実行

書き直し、実行してみました。

結果は、余分なものが取れきれいなデータになりました。

これで、書き込みの見通しも立てることができるようになりました。

しかし、ここまでに要した時間はかわらず20秒弱のままです。

読み込みに要する時間

どの過程が遅いのか確認してみることにしました。

ですので、ソート部分を取り除いたコードを実行してみました。

copy

use encoding_rs::SHIFT_JIS;
use std::error::Error;
use std::fs;

fn run() -> Result<(), Box<dyn Error>> {
    let path = "./input.csv";
    let buf = fs::read(path).unwrap();
    let (dec, _, _) = SHIFT_JIS.decode(&buf);
    let text = dec.into_owned();
    let lines = text.lines();

    let mut elements = Vec::new();
    for (i, s) in lines.enumerate() {
        if i == 0 || s.trim().len() == 0 {
            continue; 
        }

        let fields: Vec<_> = s
            .split(",")
            .map(|field| field.trim())
            .collect();
        elements.push(fields);
    }

    for i in 0..50 {
        println!("{},{}", elements[i][0], elements[i][1]);
    }

    Ok(())
}

fn main() {
    if let Err(err) = run() {
        println!("{:?}", err);
    }
}

実行結果

要した時間は3秒ほどでした。

ソート部分のコードが遅いようです。

速度向上、書き出しの研究を継続していきます。