在 Rust Hashmap 中插入元素時應該注意的事項
在對代碼進行優化時,如果想在 hashmap、hashset 或任何類似的結構中插入元素,需要注意一個事項。
你可能想在代碼中做以下一些事情:
use std::collections::HashMap;
fn main() {
let mut map: HashMap<&str, u32> = HashMap::new();
map.entry("poneyland").or_insert(3);
assert_eq!(map["poneyland"], 3);
}
但是如果在插入時需要做更多的工作呢?可以這樣做:
map.entry("poneyland").or_insert(do_something);
這裏的問題是,如果鍵 “poneyland” 已經存在於 hashmap 中,do_something 仍然會被調用。如果 do_something 消耗時間或 CPU,那麼代碼的性能將會下降。
在這裏,你應該做的是使用 or_insert_with 方法,並像這樣傳遞一個閉包:
map.entry("poneyland").or_insert_with(|| {
do_something()
};
這裏編寫了一些快速測試的代碼,以便你可以自己進行驗證:
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use std::{thread, time};
fn compute_value_to_insert() -> usize {
println!("My insertion function starts.");
thread::sleep(time::Duration::from_secs(2));
println!("My insertion function finished.");
0
}
#[test]
fn or_insert() {
let mut h: HashMap<usize, usize> = HashMap::new();
h.insert(0, 0);
h.entry(0).or_insert(compute_value_to_insert());
}
#[test]
fn or_insert_with() {
let mut h: HashMap<usize, usize> = HashMap::new();
h.insert(0, 0);
h.entry(0).or_insert_with(|| compute_value_to_insert());
}
}
當執行 or_insert 測試時,結果如下:
running 1 test
test tests::or_insert ... ok
test result: ok. 1 passed; 0 failed; finished in 2.00s
當執行 or_insert_with 測試時,結果如下:
running 1 test
test tests::or_insert_with ... ok
test result: ok. 1 passed; 0 failed; finished in 0.00s
從測試結果可以看出,當使用 or_insert 方法時,執行完成時間是 2 秒;當使用 or_insert_with 方法時,執行完成時間是近乎 0 秒。性能提升還是很明顯的。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/u8LDBtzaAJwx26odZb6j_A