मैं एक एसटीएल (जी ++) प्राथमिकता_क्यू के प्रदर्शन की तुलना कर रहा हूं और पाया कि पुश और पॉप उतनी तेज नहीं हैं जितनी मैं अपेक्षा करता हूं। निम्नलिखित कोड देखें:एसटीएल प्राथमिकता_क्यू इस मामले में मल्टीसेट से ज्यादा तेज क्यों नहीं है?
#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();
}
मैं इस -O3 संकलित और फिर भाग गया valgrind --tool = callgrind, KCachegrind testMap कुल सीपीयू testPriorityQueue का 54% लेता है सीपीयू
का 44% लेता है (बिना - ओ 3 testMap testPriorityQueue) समारोह testPriorityQueue के लिए समय के सबसे अधिक लेने के लिए लगता है कि
void std::__adjust_heap<__gbe_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, long, int, std::less<int> >
कि समारोह लगता है कहा जाता है पॉप से कहा जाने की तुलना में बहुत तेजी से होता है() कहते हैं।
यह फ़ंक्शन वास्तव में क्या करता है? क्या एक अलग कंटेनर या आवंटक का उपयोग करके इसे टालने का कोई तरीका है?
नहीं ढेर कैश-अमित्र हैं? कम से कम यह मेरी सामान्य छाप है। – Mehrdad
और मुझे लगता है कि वे अप्रत्याशित तरीकों से बहुत शाखा बनाते हैं। यह फ़ंक्शन ऐसा लगता है कि "बबलिंग" ढेर के लिए ज़िम्मेदार क्या है जो कि लॉग (एन) ऑपरेशन है जिसे हर बार एक ऑब्जेक्ट को अपने ऑर्डर को बनाए रखने के लिए ढेर पर किया जाना चाहिए। – Wug
CPU% प्रदर्शन या गति का परीक्षण करने का एक उपयोगी तरीका नहीं है। '__adjust_heap' प्राथमिकता कतार" रीबैलेंस ", और प्रियेटी कतारों से निपटने के दौरान एकमात्र धीमा ऑपरेशन है। यह प्राथमिक कतारों के लिए अंतर्निहित है, एकमात्र विकल्प जिसे मैं सोच सकता हूं वह है 'std :: set' जिसे समान तरीके से संतुलित करना है। –