C ++:for循环迭代所花费的时间

时间:2015-11-30 12:43:22

标签: c++

就像一个实验一样,我一直在运行以下代码块。我估计for循环中不同迭代次数的时间。

std::vector<double> numIt= {1e2, 1e4, 1e6, 1e8, 1e9, 1e10,1e11};
for(int i=0; i< (int) numIt.size() ; i++ )
{
    int tmp=0;
    std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
    for (int j=0; j< numIt[i]; j++)
    {
        tmp=i-j;
    }

    std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
    auto durationFPextraction = std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count();
    std::cout <<i<< "\t"<< tmp<<"\t"<<numIt[i] << "\t" << durationFPextraction <<std::endl;
}

它会打印以下内容,并且现在已经运行了几个小时来迭代1e+10长度for循环。如果所用的时间是线性的,那么它是否需要~14000毫秒(14秒)?

0 -99 100 0 1 -9998 10000 0 2 -999997 1e+06 2 3 -99999996 1e+08 144 4 -999999995 1e+09 1394

3 个答案:

答案 0 :(得分:2)

有几个问题。

  1. 请勿使用c-style演员。
  2. 请勿使用intvector进行迭代,size_t类型是正确使用的类型。
  3. 您正在测量低于测量误差阈值的物体,因此数字将始终不可靠。
  4. 为了正确测量,请使用类似:https://github.com/google/benchmark的内容,确保运行足够的迭代以获得统计信心。

答案 1 :(得分:1)

正如David Schwartz所说,这句话

  

for(int j = 0; j&lt; numIt [i]; j ++)

不合适,因为它可能是32位值,无法表示numIt向量中的1e10和1e11值。将代码更改为使用long long(64位值)时,它将继续循环。

#include <vector>
#include <chrono>
#include <iostream>

int main (int argc, char *argv[])
{
    std::vector<double> numIt= {1e2, 1e4, 1e6, 1e8, 1e9, 1e10, 1e11};
    for(size_t i=0; i< numIt.size() ; i++ )
    {
        int tmp=0;
        std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
        for (long long j=0; j< numIt[i]; j++)
        {
            tmp=i-j;
        }
        std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
        auto durationFPextraction = std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count();
        std::cout <<i<< "\t"<< tmp<<"\t"<<numIt[i] << "\t" << durationFPextraction <<std::endl;
    }
}

答案 2 :(得分:1)

int很可能是32位。

如果是这种情况,那么一旦你的int达到值2 ^ 31 - 1,将它增加1就会产生未定义的行为。实际上,未定义行为的结果通常是将int设置为最小可能值 - (2 ^ 31)。在经过另外2 ^ 32次迭代之后,你回到2 ^ 31-1,然后j变为 - (2 ^ 31),依此类推,因为j&lt; 1e10永远是真的。

您的代码永远不会完成运行。