私はSTL(g ++)priority_queueのパフォーマンスを比較しています。プッシュとポップは予想通り高速ではありません。以下のコードを参照してください。私はこの-O3をコンパイルした後、valgrindの--tool = callgrind、KCachegrind testMapを実行この場合、STL priority_queueはマルチセットよりもあまり速くないのはなぜですか?
#include <set>
#include <queue>
using namespace std;
typedef multiset<int> IntSet;
void testMap()
{
srand(0);
IntSet iSet;
for (size_t i = 0; i < 1000; ++i)
{
iSet.insert(rand());
}
for (size_t i = 0; i < 100000; ++i)
{
int v = *(iSet.begin());
iSet.erase(iSet.begin());
v = rand();
iSet.insert(v);
}
}
typedef priority_queue<int> IntQueue;
void testPriorityQueue()
{
srand(0);
IntQueue q;
for (size_t i = 0; i < 1000; ++i)
{
q.push(rand());
}
for (size_t i = 0; i < 100000; ++i)
{
int v = q.top();
q.pop();
v = rand();
q.push(v);
}
}
int main(int,char**)
{
testMap();
testPriorityQueue();
}
は総CPUの54%を取る testPriorityQueueはなし(CPU
の44%を取ります - O3 testMapがtestPriorityQueue) popから呼ばれるように
void std::__adjust_heap<__gbe_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, long, int, std::less<int> >
この関数はそう
と呼ばれるtestPriorityQueueのためのほとんどの時間を取るように思われる機能よりもはるかに高速です()コール。
この機能は何を正確に行いますか?別のコンテナやアロケータを使用して回避する方法はありますか?
はヒープキャッシュ無愛想ではありませんか?少なくともそれは私の一般的な印象でした。 – Mehrdad
そして私は彼らが予測できない方法で多くを分けていると思う。その関数は、ヒープ上で実行されるlog(n)操作であるヒープ "バブリング"の原因のように見えます。この操作は、その順序を維持するために要素が削除されるたびに実行されます。 – Wug
CPU%は、パフォーマンスやスピードをテストするのに便利な方法ではありません。 '__adjust_heap'は優先度キューを「再調整」し、プリオティティキューを扱うときは唯一の遅い操作です。先行するキューには本質的なものがありますが、私が考えることのできる唯一の代替手段は、同様の方法でバランスをとらなければならない 'std :: set'です。 –