小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

[高效數(shù)據(jù)結(jié)構(gòu)漫談]:HashMap與Vec的性能(1)

 godxiasad 2024-11-26 發(fā)布于北京

我都快忘記我還是碼農(nóng)了

遇上了一個問題,所以寫個文章記錄一下……

HashMap與Vec的性能

注意,因?yàn)檫@里主要用Rust來論述這個問題,如果對應(yīng)到Python,就是dict與list,效果是一樣的。

看到這個問題,可能很多同學(xué)都會說,這個還要你說?HashMap的是基于kv結(jié)構(gòu)的,查詢復(fù)雜度是O(1),而Vec的查詢復(fù)雜度是O(n),是個人都知道HashMap的復(fù)雜度高啊。
呵呵……圖樣圖森破,拿衣服……

看下面這個場景:

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));
//生成一個隨機(jī)年齡
let age = rng.gen_range(22..=60);
vec_info.push((name.to_owned(), age));
hashmap_info.insert(i, (name.to_owned(), age));
}
我分別定義了一個hashmap和一個vec,默認(rèn)容量都是100萬
小貼士:在Rust、CPP一類編譯型語言中,預(yù)先對集合進(jìn)行內(nèi)存分配,可以有效的提高內(nèi)存使用率和程序效率。
然后定義了一個數(shù)據(jù)結(jié)構(gòu),分別存儲了模擬的人員信息,例如一個姓名一個年齡,并且把這個數(shù)據(jù)存入到我們的hashmap和vec中,存進(jìn)去的信息類似下面這種:

vec:

vec里面直接按照數(shù)值序列進(jìn)行存儲,我們可以把序列號認(rèn)為的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),
……
}

然后隨機(jī)讀取其中的1000個信息:

//隨機(jī)訪問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();

//隨機(jī)訪問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í)行結(jié)果如下:

?。?!

vec的下標(biāo)隨機(jī)訪問,100萬里面獲取其中的1000條,比hashmap通過key進(jìn)行隨機(jī)訪問,快了20%效率。

實(shí)際上,我們回憶一下數(shù)據(jù)結(jié)構(gòu),大家就能想起來,原文是這樣說的:
?HashMap?是一種基于哈希表的數(shù)據(jù)結(jié)構(gòu),用于存儲鍵值對(key-value pairs),其中每個鍵都是唯一的。HashMap提供了快速查找、插入和刪除操作,平均時間復(fù)雜度為O(1)。
注意,理論上,hashmap是O(1)的,但是在具體實(shí)現(xiàn)的時候,不同的語言設(shè)計(jì)會出現(xiàn)一定的開銷,而vec的下標(biāo)訪問,幾乎是無開銷的直接訪問內(nèi)存,所以性能高了差不多20%。
說到這里,如果有同學(xué)要Java做同類的測試,發(fā)現(xiàn)hashmap的性能可能更慘,是因?yàn)镴ava的HashMap實(shí)現(xiàn)用的是紅黑樹來實(shí)現(xiàn)的,而紅黑樹的查詢復(fù)雜度是O(logn)……
接下去看看,遍歷的性能:
我們直接遍歷整個集合,并且取出來每個數(shù)值,這里就不進(jìn)行print了,因?yàn)閜rint的開銷還是挺大的,會卡半天,結(jié)果如下:

vec進(jìn)行全集合遍歷的性能,幾乎是比hashmap遍歷快了230%……

結(jié)論:

如果是通過下標(biāo)直接訪問,或者遇上需要遍歷全部信息的情況下,vec的性能要比hashmap更好。
那么如果是增加刪除修改呢?誰的性能更好?請聽下回分解。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多