C++ 高性能堆排序
我有一个大小超过500万的向量,每次我都想从向量中选取一个键最小的元素,并对这个元素进行一些处理。然而,在处理这个特定元素的过程中,向量中的所有剩余元素也将受到影响,因此它们的键将被更新。所以下次如果我想从向量中提取具有最小键的元素,我必须再次对向量排序。问题是从向量中提取最小元素的数量将高达50万,因此程序运行速度非常慢。为了让您更清楚地理解,我可以编写以下代码来说明:C++ 高性能堆排序,c++,performance,sorting,parallel-processing,binary-heap,C++,Performance,Sorting,Parallel Processing,Binary Heap,我有一个大小超过500万的向量,每次我都想从向量中选取一个键最小的元素,并对这个元素进行一些处理。然而,在处理这个特定元素的过程中,向量中的所有剩余元素也将受到影响,因此它们的键将被更新。所以下次如果我想从向量中提取具有最小键的元素,我必须再次对向量排序。问题是从向量中提取最小元素的数量将高达50万,因此程序运行速度非常慢。为了让您更清楚地理解,我可以编写以下代码来说明: void function(vector<MyObj*>& A) { //A.size() is nea
void function(vector<MyObj*>& A)
{ //A.size() is near 5 million, maybe even more such as 50 million.
make_heap(A.begin(), A.end(), compare); // compare function is self-defined.
for (int i=0; i<500000; i++)
{
MyObj* smallest_elem = A.front();
pop_heap(A.begin(), A.end());
A.pop_back();
Process_MyObj(smallest_elem); // here all of the elements
// in A will be affect, causing
// their keys changed.
make_heap(A.begin(), A.end()); // Since all elements' keys in A changed,
// so heap sorting A once again is
// necessary in my viewpoint.
}
}
void函数(向量&A)
{//A.size()接近500万,甚至可能更多,比如5000万。
make_heap(A.begin(),A.end(),compare);//compare函数是自定义的。
对于(inti=0;i,您可以尝试对向量排序并按顺序拾取元素,而不是使用堆
它不会提高big-o的复杂度,但可能会提高常量因子。如果进程MyObj确实影响了A中所有元素的键,我认为你做不了什么。如果它只修改了一些键,你可以编写代码来更新堆中的各个元素
由于您的代码是现在的,我看不出您从构建堆中获得了什么。我只需进行线性扫描以找到最小元素,将其与最后一个元素交换,然后弹出最后一个元素。有多少时间在进程中,以及有多少时间在堆操作中--
50/50%,80/20%?
这很重要,因为你想平衡两者。
考虑下面的一般设置:
Make a Todo list
Loop:
work on items ...
update the Todo list
太多的时间更新列表意味着没有足够的时间做真正的工作。
因此,首先测量进程/堆时间的比率。
一个便宜的方法是用它做第二次跑步
处理\u MyObj
和比较
两次,例如
P + H = 1.0 sec
2P + H = 1.7 sec
=> P = .7, H = .3: P / H = 70 % / 30 %.
make_heap
以线性时间运行--
看--
因此,加速将是困难的。
如果值是常量,则
64位缓存比指针更高效
在cstheory.stack上列出了几十篇论文,大部分是理论论文,
但是一两个可能与你的问题有关
真正的加速几乎总是针对具体问题,而不是一般问题。
你能告诉我们更多关于真正的问题吗
补充:如果大多数持久性有机污染物都是小的,而且是大的,
尝试在大排序列表前面放置一个小缓存堆。伪代码:
push:
push( cacheheap )
pop:
return min( cacheheap, bigsortedlist )
如果cacheheap
保留在真正的cpu缓存中,这可能会很有效;ymmv。
(你可能会作弊,让bigsortedlist
不准确,而不是每次都排序。)是-线性扫描是O(N),因此比排序是O(N log N)要好@user515430同意。构建堆似乎毫无用处。我这么做只是因为它来自一篇著名的论文,这也让我感到困惑。处理过程如何影响所有其他元素有什么模式吗?真的是所有元素(在这种情况下,下限显然是O(N))还是一些?它们可以增加和减少吗?