短函数c++的执行时间

Execution time of a short function c++

我想计算一个非常小的函数的执行时间,以比较递归函数与迭代函数的执行时间。

当然,如果分辨率不够,clock() 根本无法做到这一点。你能告诉我如何使用其他时间源,如 GetThreadTimes()。在微软网站上看到了描述,没看懂原理。

此外,<chrono> header 在 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();
}

只需搜索 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循环的消耗可以忽略不计

一个解决方案是按照@amchacon 的建议进行多次迭代。这样做的好处是简单明了。

它的缺点是可能导致不准确或不正确的结果,这既是由于编译器使用不同的启发式内联 and/or 指令流水线,也是由于指令和数据缓存在第一次迭代后已经预热.
因此,虽然您的函数可能确实由于错误的内存访问模式而性能很差(可能导致两次缓存未命中,每次都花费您 500 个周期),但当您 运行 函数一百次时,这可能根本不会显示,如果缓存行的总集合适合缓存。

有哪些选择?

a) 不适用于你的问题(因为你想测试递归算法),但我还是会针对 "general" 的情况说明它:使用 IACA。它专为对一小段代码进行微基准测试而设计,直至指令。

b) 使用精度更高的计时器或使用 根本不是计时器的计时器。为此,您可以在 Windows 下使用 QueryPerformanceCounterQueryThreadCycleTime(Vista 及更高版本)。周期可能比时间更可取,具体取决于您要测量的内容。

c) 查询 thread times。在我看来,这是最好的方法,因为您可以获得可靠、精确、准确的时间(与计时器非常不同,它可能包括上下文切换和在其他进程中花费的时间!),并且它适用于任何类型的代码,让您区分内核和用户时间,以防您的代码调用系统函数,并区分 CPU 和墙时间。
在函数 运行 之前和之后分别调用 GetThreadTimes 一次,然后分别减去 UserTimeKernelTime 值。
或者,如果您也对 wall time 感兴趣,则启动一个工作线程(对于 wall time,您将从 ExitTime 中减去 CreationTime,并且您显然只会得到有效的 ExitTime after 线程已经退出!)。如果您的代码还涉及阻塞 I/O 操作,计算挂钟时间可能会有用。