为什么循环中的经过时间与迭代次数不成比例

时间:2015-04-18 15:11:36

标签: c++ loops for-loop time benchmarking

我写了以下代码

#define TimeCode(Code) \
{\
    clock_t t1 = clock();\
    Code \
    clock_t t2 = clock();\
    double elapsed = (t2 - t1) * 1.0 / CLOCKS_PER_SEC;\
    std::cout << "Elapsed time " << elapsed << " sec" << std::endl; \
}

void loop(int nz)
{
    for (int i = 0; i < 5400; i++)
    {
        for (int j = 0; j < 5400; j++)
            for (int k = 0; k < nz; k++)
                ;
    }
}

int main(int argc, char* argv[])
{

    TimeCode(loop(17);)
    TimeCode(loop(34);)
    TimeCode(loop(649);)

    return 0;
}

我用g++ -o main main.cpp编译了它。结果是

Elapsed time 0.85579 sec
Elapsed time 3.14095 sec
Elapsed time 53.7562 sec

那么经过的时间如何与循环大小不成比例?

1 个答案:

答案 0 :(得分:1)

由于你的循环结构,它不能严格成比例:对于loop(n),你执行:

  • i的一次初始化,5400次增量和i
  • 的比较
  • 5400 j的初始化,5400 * 5400增量和j
  • 的比较
  • 5400 * 5400初始化k,5400 * 5400 * n增量和k
  • 的比较

这是29 165 401固定初始化,29 165 400固定增量和比较,以及29 160 000 * n次迭代和比较。所以你无法获得比例计时。

如果你想要更具比例的东西,你应该使k循环是外部的

void loop(int nz)
{
    for (int k = 0; k < nz; k++)
        for (int i = 0; i < 5400; i++)
            for (int j = 0; j < 5400; j++)
                ;
}

我建议您切换到计时high resolution clock

#define TimeCode(Code, n) \
{\
    high_resolution_clock::time_point t1 = high_resolution_clock::now();\
    Code (n);\
    high_resolution_clock::time_point t2 = high_resolution_clock::now();\
    double elapsed = duration_cast<milliseconds>(t2 - t1).count();\
    std::cout << "Elapsed time " << elapsed << " ms -> " << elapsed/n << std::endl; \
}

通过这两项更改,在我的PC上,在所有三种情况下,我每次迭代获得72到73毫秒。

三个结果之间测量的微小差异小于时钟分辨率的真空度(在Windows平台上+/- 15 ms)。考虑到这一点(但不确定性取决于平台),我将宏中的输出行更改为:

std::cout << "Elapsed time " << elapsed << " ms -> " << elapsed/n << " inaccuracy:" <<(elapsed-15)/n<<" - "<<(elapsed+15)/n<<std::endl; \

这里是最终结果: enter image description here