2012-10-29 50 views
0

是否可以刪除以下循環中的分支。所有的迭代器是從容器類型std::map<type_name, T>在C++中優化if-else分支的一個小循環

record_iterator beginIter = lastLookup_;                                                                                
    record_iterator endIter = lastLookup_;                                                                                
    ++endIter;                                                                                       
    for(;endIter != end(); ++beginIter, ++endIter){                                                                              
    time_type now = beginIter->first;                                                                                 
    if(ts == now){                                                                                      
     lastLookup_ = beginIter;                                                                                   
     return beginIter;                                                                                     
    }else if(ts > now && ts <= endIter->first){                                                                               
     lastLookup_ = beginIter;                                                                                   
     return endIter; 
    } 
    } 

,這種算法中試圖解決的是優化其假定位置相同或正向查找問題(不太遠)最後的向前擡頭位置。理想情況下,我保留最後一次查找位置的迭代器,併線性前進。但是,這似乎有相同的性能,

record_iterator it= sliceMap_.find(ts);                                                                                
    if(it !=end()){                                                                                      
    return it;                                                                                       
    }else{                                                                                        
    return sliceMap_.upper_bound(ts);                                                                                 
    }   

我覺得這個問題是分支,因此可以去除分支在此代碼,所以我可以分析在速度上有什麼不同?

+0

ts從哪裏來? – Caribou

+0

@John可能是函數的參數,說他在看的地方 – Yakk

+2

除非你的地圖很大,並且你的結果非常接近'beginIter',我認爲後者會更快,因爲它沒有橫向RB的開銷 - 按順序排列。 –

回答

5

有三大問題與第一種方法:

您的第二種方法也存在問題。你正在搜索兩次。

你爲什麼不只是使用

return sliceMap_.lower_bound(ts); 

這應該做的正是你想要一個對數搜索什麼。

2

正如有些人所說,第一種方法沒有多大意義,因爲您正在對有序容器進行線性搜索。我意識到位置應該是近lastLookup

關於第二種方法,我認爲一個簡單的優化將消除第二次查找。你正在做一個record_iterator it = sliceMap_.find(ts);上的另一個返回sliceMap_.upper_bound(ts);

編輯:
試試做這種方式:

record_iterator it = sliceMap_.lower_bound(ts);                                                                                
return it;                                               

我們都是在那裏做,用LOWER_BOUND()查找第一個元素,其關鍵不超過TS比較少(即包含一個與upper_bound()不相同的元素)。

+2

你不想在這裏添加1('it ++')。函數'lower_bound'可能是錯誤的。該名稱暗示返回值是小於或等於提供的密鑰的最後一個元素。這不是它的工作原理。而lower_bound則返回不小於提供的鍵的第一個元素。例如,如果映射中的鍵是1.0和2.0,lower_bound(1.5)將返回指向key = 2.0而不是1.0的值的迭代器。 –

+0

@DavidHammen你是對的,我相應地編輯了它,謝謝! – imreal

+1

根據您的修改,我將我的downvote更改爲upvote。我曾經被'lower_bound'弄糊塗,直到我意識到它只是錯誤的名稱。它應該被命名爲map :: least_upper_bound。 –