Day 5:效能優化基礎

學習目標

  • 用迭代器取代手寫迴圈
  • 用預分配避免重複 realloc
  • 用 &str 取代 String(零成本抽象)

今日重點

迭代器取代迴圈

// 迴圈版
fn sum_of_squares_loop(n: u32) -> u32 {
    let mut sum = 0;
    for i in 1..=n {
        sum += i * i;
    }
    sum
}

// 迭代器版(Rust 慣用、易讀)
fn sum_of_squares(n: u32) -> u32 {
    (1..=n).map(|x| x * x).sum()
}

迭代器在編譯期向量化,通常不會比手寫迴圈慢,甚至更快。

預分配(avoid realloc)

fn create_vec(size: usize) -> Vec<i32> {
    let mut v = Vec::with_capacity(size);   // 一次分配夠大的空間
    for i in 0..size {
        v.push(i as i32);
    }
    v
}

若不用 with_capacity,push 會在容量不足時反覆「重新分配 + 複製」,很慢。預先宣告容量可避免。

&str 而非 String

fn process(input: &str) -> String {
    input.to_uppercase()   // 只讀輸入,用 &str 不必擁有
}

參數用借用(&str)避免不必要的複製/所有權轉移。

練習

// 1. 用迭代器把雙倍的偶數收集起來
let evens: Vec<i32> = (0..100).filter(|x| x % 2 == 0).map(|x| x * 2).collect();

// 2. 用 with_capacity 建立可裝 1000 個元素的 Vec
let mut big = Vec::with_capacity(1000);
for i in 0..1000 { big.push(i); }
3. 比較有無 with_capacity 的巨大資料差異(可用時間戳測量或查文件)。

自我檢查

  • 慣用迭代器替代迴圈
  • 會用 Vec::with_capacity 預分配
  • 知道參數用借用減少複製
  • 具備基本的效能直覺

深入連結

  • The Rust Performance Book