簡體   English   中英

陣列與地圖的性能

[英]performance of array vs. map

我必須遍歷大型數組中元素的子集,其中每個元素都指向另一個元素(問題來自於檢測大圖中的連接組件)。

我的算法如下:1.考慮第一個元素2.將下一個元素視為上一個元素所指向的元素。 3.循環直到沒有發現新元素為止。4.考慮1-3中尚未考慮的下一個元素,回到1。請注意,要考慮的元素數比元素總數小得多。

對於我現在看到的內容,我可以:

//create a map of all element, init all values to 0, set to 1 when consider
map<int,int> is_set; // is_set.size() will be equal to N

要么

//create a (too) large array (total size), init to 0 the elements to consider
int* is_set = (int*)malloc(total_size * sizeof(int)); // is_set length will be total_size>>N

我知道訪問map中的鍵是O(log N),雖然它僅對數組恆定,但是我不知道malloc在創建時是否不是更昂貴,同時還需要更多的內存?

如有疑問,請測量兩種選擇的性能 這是唯一確定哪種方法對您的應用程序最快的唯一方法。

也就是說,一次性大型malloc通常並不十分昂貴。 同樣,盡管映射為O(log N),但根據我的經驗,至少對於std::map實現,big-O會隱藏相對較大的常數。 我發現在這種情況下使用數組方法更快並不感到驚訝,但是唯一可以肯定的方法就是測量。

還要記住,盡管映射沒有很大的前期內存分配,但是在對象的整個生命周期中它都有許多小的分配(每次插入新元素時,都會得到另一個分配,並且每次刪除元素,您將獲得另一個免費)。 如果您有很多這些,那可能會使您的堆碎片化,這可能會對性能產生負面影響,這取決於您的應用程序同時可能在做什么。

如果索引搜索適合您的需求(如常規C樣式數組提供的那樣),則std::map可能不是適合您的類。 相反,如果需要動態運行時分配,請考慮使用std::vector如果集合的大小是固定的,並且僅需要C語言風格指針的最快邊界安全替代方法,則考慮使用std::vector std::array

您可以在上一篇文章中找到更多信息。

我知道訪問map中的鍵是O(log N),雖然它僅對數組恆定,但是我不知道malloc在創建時是否不是更昂貴,同時還需要更多的內存?

映射中的每個條目都是動態分配的,因此,如果動態分配是一個問題,它將在映射中成為更大的問題。 從數據結構開始,您可以使用位圖而不是普通的int數組。 在具有32位int的體系結構中,這將使數組的大小減少32倍,在大多數情況下,將索引映射到數組中的額外成本將比額外內存的成本小得多,因為結構更多緊湊,可以容納更少的緩存行。

還有其他要考慮的因素,例如集合中元素的密度是否很小。 如果條目很少(即圖形稀疏),則可以選擇其中任何一種。 作為最后的選擇,您可以通過使用pair<int,int>的向量並將它們短化來手動實現地圖,然后使用二進制搜索。 這將減少分配數量,在排序上產生一些額外成本,並提供比映射更緊湊的O(log N)解決方案。 盡管如此,我還是會嘗試使用位掩碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM