我想到了std :: set的一個奇怪的行爲。std ::設置快而慢,發生了什麼?
下面是代碼:
#include <cstdio>
#include <windows.h>
#include <stdlib.h>
#include <vector>
#include <set>
using namespace std;
int main(int argc, char *argv[])
{
set<int> b[100];
for (int o=0; o<10; o++)
{
int tt = GetTickCount();
for (int i=0; i<5000000; i++)
{
b[o].insert(i);
}
tt = GetTickCount() - tt;
b[o].clear();
printf("%d\n", tt);
}
return 0;
}
我在Windows XP上運行。
以下是有趣的部分: 這第一次打印時間大約是3500毫秒,而所有下一個超過9000毫秒! 這是爲什麼發生?
哦,這隻發生在發佈版本(-O2優化)。
它不會發生在Linux上(在改變代碼編譯之後)。
還有一件事:當我在使用英特爾VTune進行性能分析時運行它時,總是需要大約3000毫秒,所以它應該是這樣。
UPDATE: 下面是一些新的代碼:
#include <cstdio>
#include <windows.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
const int count = 10000000;
int **a = new int*[count];
for (int o=0; o<10; o++)
{
int ttt = GetTickCount();
for (int i=0; i<count; i++)
{
a[i] = new int;
*a[i] = i;
}
int ttt2 = GetTickCount();
for (int i=0; i<count; i++)
{
int r1 = rand() * 10000 + rand();
int r2 = rand() * 10000 + rand();
r1 = r1%count;
r2 = r2%count;
int *e = a[r1];
a[r1] = a[r2];
a[r2] = e;
}
int ttt3 = GetTickCount();
for (int i=0; i<count; i++)
{
delete a[i];
}
int ttt4 = GetTickCount();
printf("%d %d\n", ttt2-ttt, ttt4-ttt3);
}
return 0;
}
這是同樣的問題。 會發生什麼是我分配許多小對象,然後以隨機順序刪除它們 - 因此它類似於它在std :: set中的樣子。 所以這是Windows內存管理問題。它不能真正處理很多小的分配和刪除。
這可能與您的標準庫/平臺的一些實現細節有關。你可以嘗試在分析器中運行它,並檢查時間花在哪裏。可能會有很多事情發生,從第一次和連續傳遞(您釋放內存)的分配方案的差異到其他任何事情。另請注意,您應該使用-O3來提高性能。 –
也許它與系統線程調度有關。你的線程不是唯一需要處理器時間的線程。您可以使用'GetThreadTimes'來查看您的線程實際消耗了多少處理器時間 – valdo
您最好的辦法可能是查看使用'-O2'生成的彙編代碼,看看有沒有什麼東西可以解釋這種行爲。 – NPE