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 に期待しているのですが試してみます。また、投稿します。