Sibainu Relax Room

柴犬と過ごす

RUST をクイックソート 4

今年最後の投稿になります。来年も元気で1年過ごせますようにと思う柴犬です。

概要

これまで、100万行をソートして Shift-Jis でファイルを作成することができませんでしたが、見直して作成できるようにしました。

また、読み取りで先頭行が漏れるコードになっていましたので修正しました。

書き出しはできましたが実行から作成まで1分50秒弱要しました。

ソートの終了まで20秒弱で、それから1分30秒と書き出しにかなりの時間を要したことになりました。

RUST は他の言語にない概念があり、独学の学習は結構難易度が高いと改めて感じました。

そして、EXCEL でCSVファイルを使う機会があるのですが、Python & Pandas のコンビと比較して身の回りの処理をRUSTで手軽に扱うことは難しいことも分かりました。

見直したコード

fn run() のみの見直しです。

とりあえず、1000行毎に文字列を連結して実行してみたところ時間を要しましたができました。

また、10000行毎もしてみましたが、体感的には変化は感じませんでした。


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();
    // ----- i を _ に変更しました。
    for (i, s) in lines.enumerate() {
        // ----- i == 0 || を削除
        if i == 0 || 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);

    // -----ここから修正
    let mut ol = String::new();
    for x in elements {
        if ol.len() == 0 {
            ol = format!("{}{}{}",x[0].clone(),",", x[1].clone());
        } else {
            ol = format!("{}{}{}", ol, "\n", format!("{}{}{}",x[0].clone(),",", x[1].clone()));
        }
    }

    let (enc, _, _) = SHIFT_JIS.encode(&ol);
    let output = enc.into_owned();

    let mut file = fs::File::create("./output.csv")?;
    file.write_all(&output)?;
    file.flush()?;
    // ----ここまで

    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();
    // ----- i を _ に変更しました。
    for (_, 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);

    // ------ここから修正
    let mut file = fs::File::create("./output.csv")?;

    let mut record = String::new();
    let mut count = 1;
    for x in elements {
        // -----最後改行にならないように
	if count == right {
            record = format!("{}",record) + x[0].clone() + "," +  x[1].clone();
        } else {
            record = format!("{}",record) + x[0].clone() + "," +  x[1].clone() + "\n";
	}

        // -----文字列を1000毎連結して書き出す
	if count % 1000 == 0 { 
            let (enc, _, _) = SHIFT_JIS.encode(&record);
            let output = enc.into_owned();
            file.write_all(&output)?;
            record = format!("{}","");
        }

        count += 1;
    }
    let (enc, _, _) = SHIFT_JIS.encode(&record);
    let output = enc.into_owned();
    file.write_all(&output)?;

    file.flush()?;
    // -----ここまで

    Ok(())
}

私の知識でRUST をちょこちょこ仕事に使うにはハードルが高いです。

現時点では Python と GO が最適だと思う次第です。

あと、Polars Lightning-fast DataFrame library for Rust and Python に期待しているのですが試してみます。また、投稿します。