我想计算一个非常小的函数的执行时间来比较递归函数和迭代函数的执行时间。
当然,clock()
根本没有足够的分辨率就无法做到这一点。你能告诉我如何使用GetThreadTimes()
之类的其他时间来源。我在微软网站上看到了一个描述,但没有理解这个原则。
此外,<chrono>
标头在MS Visual 10中不起作用。
代码:
int search (int a[], int size, int& num) {
if (size >0) {
if (a[size-1] == 17) {num = size-1; return num;}
else {return search (a, --size, num);}}
else {return num=-1;};
}
int searchit (int a[], int size, int& num) {
for (int i =0; i< size; i++) {
if (a[i] == 17) {num = i;}
else num = -1;
}
return num;}
int main () {
srand ((unsigned int) time(0));
int num = 0;
const int size = 40;
int a[size];
for (int i =0; i< size; i++) {
a[i] = rand()%100;
cout << a[i] << endl;}
cout << '\n';
search (a, size, num);
cout << num << endl;
cin.get();
cin.ignore();
}
答案 0 :(得分:3)
一种解决方案是按照@amchacon的建议进行多次迭代。这样做的优点是简单易行。
由于编译器使用不同的启发法进行内联和/或指令流水线操作,并且由于指令和数据缓存在第一次迭代后已经预热,因此它的缺点是可能导致不准确或不正确的结果。
因此,虽然由于内存访问模式不良导致您的功能确实可能性能相当差(可能导致二十多次缓存未命中,每次花费500个周期),但如果运行该功能一百次,则可能根本不显示一组缓存行适合缓存。
有哪些替代方案?
a)不适用于你的问题(因为你想测试一个递归算法),但无论如何我会说“一般”情况:使用IACA。它专门用于对指令的一小部分代码进行微基准测试。
b)使用更高精度的计时器或使用完全不是计时器的计时器 。为此,您可以在Windows下使用QueryPerformanceCounter
和QueryThreadCycleTime
(Vista及更高版本)。循环可能比时间更受欢迎,具体取决于您要测量的内容。
c)查询thread times。这是我认为最好的方法,因为你可以获得可靠,精确,准确的时间(很不像计时器,可能包括上下文切换和在其他进程中花费的时间!),它适用于任何类型的代码,让你区分内核和用户时间,以防您的代码调用系统功能,并区分CPU和墙上时间
在运行您的函数之前和之后调用GetThreadTimes
一次,并减去相应的UserTime
和KernelTime
值。
或者,如果您对壁挂时间也感兴趣,请启动工作线程(对于待机时间,您将从CreationTime
中减去ExitTime
,并且您显然只会获得有效的ExitTime
线程退出了!)。如果您的代码还涉及阻止I / O操作,则计算挂起时间可能很有用。
答案 1 :(得分:2)
只需进行100次搜索并取平均值:
time_t begin,end,total;
const int iterations = 100;
begin = clock();
for (int i = 0;i<iterations;i++)
search (a, size, num);
end = clock();
total = (end-begin)/static_cast<double>(CLOCKS_PER_SEC);
cout<<"Average time for "<<iterations<<" iterations: "<<total/iterations<<endl;
编译器将展开for循环:)。无论如何,For循环的消耗可以忽略不计。