2015-05-21 47 views
1

next()advance()之間的性能有任何差異嗎?我問,因爲我的代碼非常慢,我試圖找出原因。for循環中迭代器函數next()與advance()的性能

我經歷了幾個不同類型的列表,並使用for循環更新三個不同的迭代器。該代碼看起來是這樣的:

listPt3d l1;  // std::list<cv::Point3d> 
listlistPt2i l2; // std::list<std::list<cv::Point2i>> 
listlistPt3d l3; // std::list<std::list<cv::Point3d>> 

listPt3d::iterator iter1, iter1_2; 
listlistPt2i::iterator iter2, iter2_2; 
listlistPt3d::iterator iter3, iter3_2; 

// compare lists with each other 
for (iter1 = l1.begin(), iter2 = l2.begin(), iter3 = l3.begin(); 
    iter1 != prev(l1.end()); 
    iter1 = next(iter1), iter2 = next(iter2), iter3 = next(iter3)) 
{ 
    for (iter1_2 = next(iter1), iter2_2 = next(iter2), iter3_2 = next(iter3); 
     iter1!= l1.end(); 
     iter1_2 = next(iter1_2), iter2_2 = next(iter2_2), iter3_2 = next(iter3_2)) 
    { 
     // whatever 
    } 
} 

我的問題是,它是否是更快地使用iterator = next(iterator)advance(iterator, 1)還是這既是相同。我可以想象,由於沒有賦值運算符,所以提前更快一點。

我避免使用++運算符,因爲我列出了列表,因此遇到了++問題。

如果有任何其他可能性遍歷for循環,那麼請告訴我,因爲我不熟悉這些事情。謝謝。

+0

我想,這不是真正的區別(你必須測量)。然而,你可能應該做的是用矢量替換你的列表。 – MikeMB

+0

我不明白爲什麼'++'對你有問題。 – Lingxi

+0

可能更重要的是「什麼」的問題 – MikeMB

回答

1

根據標準(本例中爲N3337),在內部調用std::next有效地調用std::advance(這不是必需的,但它的行爲如此)。因此,std::advance理論上更有效率,但在實踐中不可能有明顯的性能差異。
值得一提的,但是,std::advance不能與r值迭代器被稱爲第一個參數(就像你從調用begin()end()

關於你對你的代碼運行緩慢的投訴得到了什麼。這不太可能是由於你如何遞增迭代器所引起的,除非你在嵌套循環體內做的很少。
既然你聲明你在那裏調用erasesplice,我很想猜測其中一個或兩個都是問題的一部分
這就是說,我會建議您在嘗試進一步o之前先剖析您的代碼ptimisations。這樣你就對你的優化做出明智的決定。

+0

我已經嘗試過使用'push_back()'來避免'splice()',並以這種方式將迭代器寫入另一個列表,例如'list.push_back(iteratorToBeSpliced)'。儘管如此,這並沒有什麼區別。但我會繼續尋找這個問題。你究竟說「分析代碼」是什麼意思?對此我不確定。 – jkl

+0

我嘗試過'++'運算符,'next()'和'advance()','advance()'實際上更快。由於其他人很慢,人們可以真正看到時間表現的差異。所以我現在會保持這樣並繼續優化。謝謝。 – jkl

+0

「分析代碼」意味着使用CPU分析程序(例如Linux上的gprof或Windows上的Visual Studio Profiler)來測量CPU花費多長時間執行代碼的各個部分。 –

-1

如果你看看他們提到的複雜性,兩者看起來都一樣。

std :: advance 複雜性 線性。 但是,如果InputIt另外滿足RandomAccessIterator的要求,則複雜度是恆定的。

std :: next 複雜度 隨機訪問迭代器的常量。 否則,線性n。

從實現的角度來看,特別是在列表案例中的進步,也許它可以跳過跳過列表..但我想它會被提及,如果是這樣的話。

+0

'std :: next'應該始終保持不變,因爲它相當於前進一個位置。 – chbaker0

+0

我有時會收到錯誤消息,表明在我的計算過程中列表迭代器不可取消。這就是我改變它的原因。我認爲它是有效的,因爲子列表長度不同。 – jkl