繁体   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