2017-04-25 114 views
1

對於for循環的清潔,我喜歡基於範圍的for循環。在for循環中,我想先填充一個我知道大小的矢量,但我缺少一個索引值。我現在有兩種方法來實現它,聲明一個向量並添加帶有push_back的元素或者創建一個初始化的向量(因爲不需要分配,應該更快一點?),計算索引並插入一個元素。考慮乾淨代碼的性能,有什麼更好

問題:相對於其他方法的性能缺陷和/或是否有更好的實現方式?

在此示例代碼下方,真實代碼包含相對少量的項目(推測可能少於10個),但它將通過此​​過程運行數百萬次。

//The vector as input for the for loop 
    std::vector<double> vecIn = { 1, 2, 3, 4, 5 }; 

    //Adding values to vectors, vector size changes on each loop right? 
    std::vector<double> vecOut1; 
    //Loop through vector with range looping 
    for (auto& val : vecIn) { 
     vecOut1.push_back(val); //In reality val is some calculated value based on the input. 
    } 

    //Adding values to initialized vector, but need to calculate index. 
    std::vector<double> vecOut2(vecIn.size()); 
    //Loop through vector with range looping 
    for (auto& val : vecIn) { 
     auto i = &val - &vecIn[0]; 
     vecOut2[i] = val; //In reality val is some calculated value based on the input. 
    } 

我喜歡短暫的第一個循環,但害怕明智的表現會更糟。

當然,我也可以在循環的開始處聲明一個索引並對其進行迭代,但這似乎有點打敗了清理的目的。

編輯:爲了澄清,這是演示代碼,我將一個向量複製到另一個向量。在實際的程序中,處理輸入向量並基於輸入向量計算新值。新值需要插入/附加到矢量輸出。在真實代碼中,輸入甚至不是矢量,而是一個boost :: ublas :: matrix。

+2

對其進行配置並查看:) –

+4

使用'vector.reserve'。 – nwp

+9

如果你想複製整個矢量,你可以做'std :: vector vecOut1 = vecIn;'這個庫會爲你做所有的工作。包括預先分配足夠的空間。 –

回答

1

你所有的第一循環所需要的是一個.reserve()在相同的數量級的性能才能發揮其作爲第二個:

std::vector<double> vecOut1; 
vecOut1.reserve(vecIn.size()); 
for (auto& val : vecIn) 
    vecOut1.push_back(val); 

reserve預先分配的要求,而不改變向量size - 所以沒有重新分配在循環中進行。

4

這幾乎是一樣的。

您可以通過執行讓編譯器優化你的東西:

std::vector<double> vecOut1(vecIn.begin(), vecIn.end()); 

std::vector<double> vecOut1 = vecIn 

通過這樣做,你要複製vecIn到vecOut1。

另一個建議:無論您是否可以告訴您在for循環中處理的類型,請避免使用關鍵字auto,並指定類型。

編輯:由於OP的問題不清楚,這裏有一個新的答案。

你的第一個aproach就好了。還有一些很好的選擇。

如果你知道你的vecOut2載體的插入元素,你可以有指數以更好的方式訪問之前的大小:

std::vector<double> vecOut2(vecIn.size()); 
for(int i = 0;i < vecOut2.size(); i++){ 
    vecOut2[i] = vecIn[i] + /* Your calculation */; 
} 

這真的取決於你想如何執行你的計算,如果計算是線性的(如果你不得不在索引之間跳轉)。

+0

我編輯了我的問題以更清楚地說明我不想執行矢量複製,但提供的代碼是示例代碼。 –

+0

我編輯了我的答案,但您仍然不清楚要如何執行您的操作以及您的計算有多複雜。 – mvs

+0

我不同意不使用自動。將整個類型的迭代器寫入複雜的數據結構非常耗時,不會使代碼更具可讀性,並且如果更改基礎數據結構,則需要重寫 –