簡體   English   中英

又一個動態陣列與std :: vector,但是

[英]Yet another Dynamic Array vs. std::vector, but

......好吧,我得到了奇怪的結果!

我很好奇std::vector與動態數組的性能。 看來已經有很多關於這個問題的問題,如果我不經常得到這些“矛盾的”結果,我就不會提到它: vector<int>new int[]更快! 我一直認為如果有任何性能差異,它總是喜歡動態數組。 這個結果怎么可能?

代碼如下:

int numElements = 10000000;
 long j = 0;
 long k = 0;

 vector<int> intVector(numElements);
 int* intArray = new int[numElements]; 

 clock_t start, finish;
 start = clock();

 for (int i = 0; i < numElements; ++i)
  intVector[i] = i;
 for (int i = 0; i < numElements; ++i)
  j += intVector[i];

 finish = clock();
 cout << "j: " << j << endl;
 cout << "Total duration: " << (double) finish - start << " ms." << endl;

 // Test Control.
 start = clock();

 for (int i = 0; i < numElements; ++i)
  intArray[i] = i;
 for (int i = 0; i < numElements; ++i)
  k += intArray[i];

 finish = clock();
 cout << "k: " << k << endl;
 cout << "Total duration: " << (double) finish - start << " ms." << endl;

優化已經開啟,我在每個開始/結束塊中分離了for循環,這樣我就可以單獨計算數組/向量的初始化時間(在這種情況下, std::vector<int>new int[]似乎執行相同的操作)。

但是,使用上面的代碼我經常得到std::vector<int>26-30 ms獲勝而new int[]36-45 ms

任何人都在關心解釋為什么矢量比動態數組表現更好? 兩者都是在時序循環之前聲明的,所以我預計性能大致相同。 此外,我嘗試了相同的想法,而不是使用std::vector<int*>new int*[]並獲得了類似的結果, vector類的性能優於動態數組,因此指針指針也是如此。

謝謝您的幫助。

附錄:如果沒有優化, std::vector會失去一個動態數組的大時間(~ 1,400 ms vs.~ 80 ms ),以達到預期的性能差異,但這並不意味着矢量類可以某種方式優化到提供比標准動態陣列更好的性能?

我的猜測是,操作系統在首次訪問之前不會分配物理內存。 vector構造函數將初始化所有元素,因此內存將在您開始計時時分配。 陣列內存未初始化(並且可能未分配),因此其時間可能包括分配。

嘗試將數組初始化更改為int* intArray = new int[numElements](); 對其元素進行值初始化,看看是否會改變結果。

出於所有實際目的,當使用這種方式時,它們的速度完全相同。 vector的operator []通常像[MSVC版本]一樣實現:

const_reference operator[](size_type _Pos) const
{   // subscript nonmutable sequence
    return (*(_Myfirst + _Pos));
}

......這與:

const_reference operator[](size_type _Pos) const
{   // subscript nonmutable sequence
    return _Myfirst[_Pos];
}

您的測試基本上只是測試編譯器內聯代碼的能力,而且它似乎在這里做得很好。

至於差異的解釋,你得到的任何答案通常都是假設的,沒有看到反匯編。 它可能與更好的緩存有關,寄存器更好地用於第一種情況(嘗試交換測試的順序,看看會發生什么),等等。值得注意的是,在測試開始之前,將訪問向量的內存。它將所有內容初始化為ctor中的T()。

不幸的是,我們不能簡單地編寫這樣的小測試,並從中得出一般結論。 在系統和優化編譯器變得如此復雜之前,我們曾經能夠做到這一點,但是現在除了現實世界的測試之外,還有太多的變量可以用來做出有意義的結論。

出於同樣的原因,我們通常期望任何認真對待性能的人積極地分析他們的代碼,因為事情已經變得非常復雜,人們無法正確地確定代碼中的瓶頸,而不是明顯的算法效率低下(我經常看到專業程序員對裝配和計算機體系結構的理解遠遠超過我在使用剖析器檢查他們的假設時所犯的錯誤。

我剛做了這個實驗。 確實有奇怪的行為,雖然我認為我弄清楚了。

再次重復您的代碼。 那是...

benchmark vector
benchmark array

benchmark vector
benchmark array

你會注意到第二次你會得到不同的數字。 我猜? 頁面錯誤。 由於某種原因,向量不會導致頁面錯誤,而數組方法會導致頁面錯誤。 頁面加載后,兩者將以大致相同的速度運行(即:第二次發生的情況)。 到目前為止,有誰知道如何打印進程中的頁面錯誤數?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM