Namaran

Code daily. Without assist.

2026-09-18

build_csv.rs

fn build_csv(fields: &[&str]) -> String {
    let mut result = String::new();
    for field in fields {
        if result.is_empty() {
            result = field.to_string();
        } else {
            result = format!("{result},{field}");
        }
    }
    result
}

build_csvは正しい結果を返しますが、fieldsが長くなるにつれて不釣り合いに遅くなります。何が問題で、どう直せばよいでしょうか?

Answer

String+は左側のStringを値で受け取り、そのバッファを再利用して追記しますが、format!マクロは既存のバッファを再利用しません。呼ぶたびに新しいStringを一から組み立て、resultの中身全体をコピーし直します。i番目のフィールドを処理する時点でresultの長さはおおよそiに比例するので、全体ではO(n²)のコピーが発生します。既存のバッファへ追記するpush_str/pushを使えば、コピーは起こらずO(n)になります:

fn build_csv(fields: &[&str]) -> String {
    let mut result = String::new();
    for field in fields {
        if !result.is_empty() {
            result.push(',');
        }
        result.push_str(field);
    }
    result
}