HashMap與Vec的性能注意,因為這里主要用Rust來論述這個問題,如果對應到Python,就是dict與list,效果是一樣的。 看到這個問題,可能很多同學都會說,這個還要你說?HashMap的是基于kv結構的,查詢復雜度是O(1),而Vec的查詢復雜度是O(n),是個人都知道HashMap的復雜度高啊。看下面這個場景: let size = 1000000; let mut rng = rand::thread_rng(); let mut vec_info:Vec<(String,i32)> = Vec::with_capacity(size); let mut hashmap_info:HashMap<usize,(String,i32)> = HashMap::with_capacity(size);
for i in 0..size{ //生成一個abc.abcde這樣格式的模擬名字 let name = format!("{}.{}",generate_random_string(rng.to_owned(),3),generate_random_string(rng.to_owned(),5)); //生成一個隨機年齡 let age = rng.gen_range(22..=60); vec_info.push((name.to_owned(), age)); hashmap_info.insert(i, (name.to_owned(), age)); }
我分別定義了一個hashmap和一個vec,默認容量都是100萬小貼士:在Rust、CPP一類編譯型語言中,預先對集合進行內(nèi)存分配,可以有效的提高內(nèi)存使用率和程序效率。 然后定義了一個數(shù)據(jù)結構,分別存儲了模擬的人員信息,例如一個姓名一個年齡,并且把這個數(shù)據(jù)存入到我們的hashmap和vec中,存進去的信息類似下面這種:vec:vec里面直接按照數(shù)值序列進行存儲,我們可以把序列號認為的ID[ ("iYP.NHqtJ", 24), ("Tr1.YITPi", 34), ("cMx.gkNIA", 58), …… ]
hashmap:hashmap里面用kv模式存儲,序列號(ID)就是他們的key{ 0: ("iYP.NHqtJ", 24), 1: ("Tr1.YITPi", 34), 2: ("cMx.gkNIA", 58), …… }
然后隨機讀取其中的1000個信息: //隨機訪問vec中的1000個記錄 let start = Utc::now(); for i in 0..1000{ let idx = rng.gen_range(0..size); println!("name= {} age = {}",vec_info[idx].0,vec_info[idx].1); } let end = Utc::now(); let vec_o = end.timestamp_subsec_micros()-start.timestamp_subsec_micros();
//隨機訪問hashmap中的1000個記錄 let start = Utc::now(); let start = Utc::now(); for i in 0..1000{ let idx = rng.gen_range(0..size); println!("{:?}",hashmap_info[&idx]); } let end = Utc::now();
在debug模式下,執(zhí)行結果如下: ?。?! vec的下標隨機訪問,100萬里面獲取其中的1000條,比hashmap通過key進行隨機訪問,快了20%效率。實際上,我們回憶一下數(shù)據(jù)結構,大家就能想起來,原文是這樣說的:?HashMap?是一種基于哈希表的數(shù)據(jù)結構,用于存儲鍵值對(key-value pairs),其中每個鍵都是唯一的。HashMap提供了快速查找、插入和刪除操作,平均時間復雜度為O(1)。 注意,理論上,hashmap是O(1)的,但是在具體實現(xiàn)的時候,不同的語言設計會出現(xiàn)一定的開銷,而vec的下標訪問,幾乎是無開銷的直接訪問內(nèi)存,所以性能高了差不多20%。說到這里,如果有同學要Java做同類的測試,發(fā)現(xiàn)hashmap的性能可能更慘,是因為Java的HashMap實現(xiàn)用的是紅黑樹來實現(xiàn)的,而紅黑樹的查詢復雜度是O(logn)……我們直接遍歷整個集合,并且取出來每個數(shù)值,這里就不進行print了,因為print的開銷還是挺大的,會卡半天,結果如下:vec進行全集合遍歷的性能,幾乎是比hashmap遍歷快了230%…… 結論:如果是通過下標直接訪問,或者遇上需要遍歷全部信息的情況下,vec的性能要比hashmap更好。那么如果是增加刪除修改呢?誰的性能更好?請聽下回分解。
|