我使用std::map
來存儲很多元素(元素對),我有一個「小」的疑問。迭代我的std::map
,iterator
或reverse_iterator
上的所有元素會更有效嗎?iterator vs reverse_iterator
回答
真的很重要嗎?這些是你必須儘量避免恕我直言的微觀優化類型。此外,即使迭代時間在地圖上的大量元素中發生變化,您嘗試遍歷如此大地圖的所有元素的事實意味着最有可能您選擇了錯誤的數據結構。
除非你對你的代碼進行了剖析,發現它們之間存在顯着差異,否則我就不會關心它。
「不成熟的優化是所有邪惡的根源。」 - Donald Knuth
可能沒有區別。 std :: reverse_iterator只是一個在編譯時將++轉換爲 - 的模板填充程序。
對於一個向量或其他連續的存儲容器,前向迭代器可能與緩存的交互性要好於反向迭代器(不太可能會檢測到),但對於基於樹的容器,根本沒有任何區別 - 不會有任何地方提到利用。
不是真的,它不僅僅是一個模板墊片。 FYI set/map reverse_iterators比正向迭代器慢2x至3倍。 – vladr 2010-03-31 00:11:34
我認爲使用reverse_iterator沒有意義;這是違反直覺的。
這會讓代碼更難理解,有人會看代碼並轉到「wtf」;如果你需要發表評論來解釋爲什麼,這可能意味着它不是最好的代碼。
我想知道是否需要迭代。 Map包含鍵值對,通常用於查找。如果由於某些原因仍然需要迭代地圖(可能會刪除地圖中包含的指針等),那麼您可以使用std::for_each。忘記微觀優化,你可以嘗試增加代碼的可讀性。
任何具體的投票原因? – 2009-05-20 19:00:34
首先,我沒有-1你,但`std :: map`被設計爲可迭代的,如果你只使用鍵值對,那麼你可能會使用像`std :: unordered_map`這樣的哈希映射。如果你需要鍵值和有序迭代,它可以很好地使用`std :: map`。 – smerlin 2011-07-25 00:19:45
爲了記錄在案,提領reverse_iterator
上std::map
和std::set
容器是慢一倍爲使用iterator
- 既-O3 GCC 3.4.6和MSVC在Intel/AMD處理器(幾乎3倍於PPC慢)同樣適用於const_reverse_iterator
與const_iterator
。這是因爲reverse_iterator
實際上是指向緊接樹節點的樹節點將被解除引用,因此需要額外的工作。 std::vector
迭代器展現出非常溫和的差異(reverse_iterator
在PPC上只有〜30%較慢,在Intel/AMD上幾乎沒有區別。)順便說一句,迭代器的迭代器速度比迭代器的迭代器速度快20倍。
#include <set>
#include <vector>
#include <stdio.h>
#ifdef _WIN32
#include <sys/timeb.h>
#else
#include <sys/time.h>
#endif
#include <time.h>
#define CONTAINER std::set<int>
double
mygettime(void) {
# ifdef _WIN32
struct _timeb tb;
_ftime(&tb);
return (double)tb.time + (0.001 * (double)tb.millitm);
# else
struct timeval tv;
if(gettimeofday(&tv, 0) < 0) {
perror("oops");
}
return (double)tv.tv_sec + (0.000001 * (double)tv.tv_usec);
# endif
}
int main() {
int i, x = 0;
CONTAINER bla;
for (i = 0; i < 10000; bla.insert(bla.end(), i++)) ;
double t1 = mygettime();
for (i = 0; i < 100; ++i) {
for (CONTAINER::iterator it = bla.begin(); it != bla.end(); ++it) {
x ^= *it;
}
}
printf("forward: %f\n", mygettime() - t1);
double t2 = mygettime();
for (i = 0; i < 100; ++i) {
for (CONTAINER::reverse_iterator it = bla.rbegin(); it != bla.rend(); ++it) {
x ^= *it;
}
}
printf("reverse: %f\n", mygettime() - t2);
return 0;
}
- 1. reverse_iterator vs iterator的性能?
- 2. GNU的reverse_iterator的<Iterator> ::操作符 - >和代理迭代
- 3. reverse_iterator適配器
- 4. 如何將DRY原理應用於C++中的迭代器? (iterator,const_iterator,reverse_iterator,const_reverse_iterator)
- 5. 函數是否可以同時接受iterator和reverse_iterator作爲參數
- 6. std :: reverse_iterator有什麼缺點?
- 7. 如何用reverse_iterator插入
- 8. C++列表迭代reverse_iterator的
- 9. std :: reverse_iterator奇怪的行爲(UB?)
- 10. reverse_iterator的行爲[]
- 11. vector :: erase and reverse_iterator
- 12. std ::等於reverse_iterator
- 13. C++ reverse iterator和eigen
- 14. 運算符!=對std :: reverse_iterator不明確C++
- 15. 從CUDA的device_ptr獲取reverse_iterator
- 16. C++與cout和reverse_iterator的
- 17. 如何計算std :: vector <int> :: iterator與std :: vector <int> :: reverse_iterator之間的距離?
- 18. 用iterator
- 19. `return iterator`和`iterator`產生的區別
- 20. Iterable vs Iterator作爲返回行爲(最佳實踐?)
- 21. C++ STL:迭代器和reverse_iterator缺少基類的代碼複製
- 22. Eigen :: RowVector Iterator
- 23. Iterator和IEnumerator
- 24. srand()和vector :: iterator
- 25. PHP:text fil esentence iterator
- 26. 'list iterator not derefereenable'
- 27. 創建`從iterator
- 28. Iterator,ListIterator和List
- 29. 在Struts2的Iterator
- 30. C++ set lower_bound()iterator
嗯,你是對的。 我想用運算符「<<」將所有元素打印到我的類中,但是如果打印所有std :: map,則耗時過長。最好不要這樣做。 謝謝 – 2009-05-20 17:56:44