高性能堆排序
High performance heap sorting
我有一个大小大于500万的向量,每次我想从向量中取出一个键值最小的元素,并对该元素进行一些处理。但是在处理这个特定元素时,vector中所有剩余的元素也会受到影响,从而使它们的键更新。所以下次如果我想从向量中取出键值最小的元素,我必须再对向量排序一次。问题是从向量中提取最小元素的次数将高达50万,因此程序运行速度很慢。为了让您更清楚地理解,我可以写下面的代码来说明:
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.
}
}
有没有办法使代码尽可能高效地运行?任何想法都是受欢迎的,不限于算法的改进,例如,并行或其他任何东西。非常感谢!
如果Process_MyObj确实影响了A中所有元素的键,我认为您可以做的不多。如果它只修改了一些键,则可以编写代码来更新堆中的单个元素。
正如你现在的代码,我不知道你从构建堆中获得了什么。我会做一个线性扫描来找到最小的元素,把它和最后一个元素交换,然后弹出最后一个元素。
您可以尝试对vector进行排序并按顺序选择元素,而不是使用堆。
它不会提高大0复杂度,但可能会提高常数因子
在Process_MyObj
中有多少时间,在堆操作中有多少时间——50/50%, 80/20% ?
这很重要,因为你想平衡两者。考虑以下一般设置:
Make a Todo list
Loop:
work on items ...
update the Todo list
花太多时间更新列表意味着没有足够的时间做真正的工作。首先测量进程/堆时间的比率。要做到这一点,一个便宜的方法是用
Process_MyObj
和compare
做两次,例如
P + H = 1.0 sec
2P + H = 1.7 sec
=> P = .7, H = .3: P / H = 70 % / 30 %.
make_heap
在线性时间内运行查看如何在最多进行3n次比较时实现stdmake-heap-所以加速会很困难。如果值是常量,则成堆的64位<32值,32索引>将比指针的缓存效率更高。
whats-new-in-purely-functional-data-structures-since-okasakicstheory。斯塔克列出了几十篇论文,大多是理论性的,但有一两个可能与你的问题有关。
真正的加速几乎总是针对特定的问题,而不是通用的。你能告诉我们更多关于真正的问题吗?
如果大多数pop都很小,而push很大,试着在大的排序列表前面放一个小的缓存堆。伪代码:
push:
push( cacheheap )
pop:
return min( cacheheap, bigsortedlist )
这可能是有效的如果 cacheheap
留在真正的cpu缓存;ymmv。
(你可能会作弊,让bigsortedlist
不准确,而不是每次都排序)
- 无法在我的堆排序代码中找到错误.无法正确执行.C++
- 堆排序,我无法弄清楚我的代码出了什么问题,输出顺序不正确
- 堆排序它不起作用或计算不正确
- 试图做堆排序,但被卡住了
- treap 中的轮换会违反它的堆排序或二叉搜索树顺序吗?
- 计算在堆排序中完成的比较次数
- 堆排序和插入排序
- 堆排序未产生正确的输出
- 结构的堆排序
- C++堆排序引发错误
- 堆排序CPU时间
- 提高循环缓冲区或堆排序性能
- C++堆排序算法在4100多个数据条目后崩溃
- 为什么我的堆排序比 Java 和 C++ 的排序函数快
- 堆排序 - 实现的复杂性
- Introsort(快速排序+堆排序)实现和复杂性
- 堆排序,堆"correctness"
- 堆排序-为什么PercolateDown()中的循环迭代(length/2)次
- 在堆排序中迭代max heapify
- 高性能堆排序