我正在尝试对线性排序等简单算法进行运行时测量。问题在于,无论我做什么,时间测量都不会按预期工作。无论我使用什么问题,我都会得到相同的搜索时间。我和其他试图帮助我的人同样感到困惑。
我有一个线性排序函数,如下所示:
// Search the N first elements of 'data'.
int linearSearch(vector<int> &data, int number, const int N) {
if (N < 1 || N > data.size()) return 0;
for (int i=0;i<N;i++) {
if (data[i] == number) return 1;
}
return 0;
}
我试图用C ++ 11中的time_t和chrono进行时间测量而没有任何运气,除了更多的小数。这就是我正在搜索时的样子。
vector<int> listOfNumbers = large list of numbers;
for (int i = 15000; i <= 5000000; i += 50000) {
const clock_t start = clock();
for (int a=0; a<NUMBERS_TO_SEARCH; a++) {
int randNum = rand() % INT_MAX;
linearSearch(listOfNumbers, randNum, i);
}
cout << float(clock() - start) / CLOCKS_PER_SEC << endl;
}
结果? 0.126,0.125,0.125,0.124,0.124,...(相同的值?)
我已尝试使用VC ++,g ++和不同的计算机上的代码。
首先我认为这是我的搜索算法实现的错误。但是像上面这样的线性排序不能变得更简单,它显然是O(N)。即使问题规模增加太多,时间如何才能相同?我不知道该怎么做。
编辑1: 其他人可能会解释为什么会这样。但它在更改后实际上在发布模式下工作: if(data [i] == number)
要:
if (data.at(i) == number)
我不知道为什么会这样,但线性搜索可能会在更改后正确测量时间。
答案 0 :(得分:3)
大约恒定执行时间的原因是编译器能够优化部分代码。
具体看这部分代码:
for (int a=0; a<NUMBERS_TO_SEARCH; a++) {
int randNum = rand() % INT_MAX;
linearSearch(listOfNumbers, randNum, i);
}
使用g ++ 5.2和优化级-O3
进行编译时,编译器可以完全优化对linearSearch()
的调用。这是因为无论是否调用该函数,代码的结果都是相同的。
linearSearch
的返回值不会在任何地方使用,并且该函数似乎没有副作用。所以编译器可以删除它。
您可以按如下方式交叉检查和修改内部循环。执行时间不应改变:
for (int a=0; a<NUMBERS_TO_SEARCH; a++) {
int randNum = rand() % INT_MAX;
// linearSearch(listOfNumbers, randNum, i);
}
循环中剩下的是对rand()
的调用,这就是您正在测量的内容。将data[i] == number
更改为data.at(i) == number
时,对linearSearch
的调用不会产生副作用,因为at(i)
可能会抛出超出范围的异常。因此,编译器不会完全优化linearSearch
代码。但是,使用g ++ 5.2,它仍会内联它而不进行函数调用。
答案 1 :(得分:0)
clock()正在测量CPU时间,也许你想要时间(NULL)?检查此issue
答案 2 :(得分:0)
start
应该在for
循环之前。在您的情况下,start
对于每次迭代都是不同的,它在{ ... }
之间保持不变。
const clock_t start = clock();
for (int i = 15000; i <= 5000000; i += 50000){
...
}