如何计算C++中代码片段的执行时间

Ahm*_*gle 118 c++ benchmarking

我必须在几秒钟内计算C++代码片段的执行时间.它必须在Windows或Unix机器上运行.

我使用以下代码代码来执行此操作.(之前导入)

clock_t startTime = clock();
// some code here
// to compute its execution duration in runtime
cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " seconds." << endl;
Run Code Online (Sandbox Code Playgroud)

但是对于小输入或短语句,例如a = a + 1,我得到"0秒"的结果.我认为它必须是0.0000001秒或类似的东西.

我记得System.nanoTime()在Java中,在这种情况下工作得很好.但是我无法从clock()C++的功能中获得相同的功能.

你有解决方案吗?

Tho*_*ini 115

你可以使用我写的这个功能.你调用GetTimeMs64()它,它使用系统时钟返回自unix纪元以来经过的毫秒数 - 就像time(NULL)毫秒一样.

它适用于Windows和Linux; 它是线程安全的.

请注意,窗口的粒度为15毫秒; 在Linux上它是依赖于实现的,但它通常也是15毫秒.

#ifdef _WIN32
#include <Windows.h>
#else
#include <sys/time.h>
#include <ctime>
#endif

/* Remove if already defined */
typedef long long int64; typedef unsigned long long uint64;

/* Returns the amount of milliseconds elapsed since the UNIX epoch. Works on both
 * windows and linux. */

uint64 GetTimeMs64()
{
#ifdef _WIN32
 /* Windows */
 FILETIME ft;
 LARGE_INTEGER li;

 /* Get the amount of 100 nano seconds intervals elapsed since January 1, 1601 (UTC) and copy it
  * to a LARGE_INTEGER structure. */
 GetSystemTimeAsFileTime(&ft);
 li.LowPart = ft.dwLowDateTime;
 li.HighPart = ft.dwHighDateTime;

 uint64 ret = li.QuadPart;
 ret -= 116444736000000000LL; /* Convert from file time to UNIX epoch time. */
 ret /= 10000; /* From 100 nano seconds (10^-7) to 1 millisecond (10^-3) intervals */

 return ret;
#else
 /* Linux */
 struct timeval tv;

 gettimeofday(&tv, NULL);

 uint64 ret = tv.tv_usec;
 /* Convert from micro seconds (10^-6) to milliseconds (10^-3) */
 ret /= 1000;

 /* Adds the seconds (10^0) after converting them to milliseconds (10^-3) */
 ret += (tv.tv_sec * 1000);

 return ret;
#endif
}
Run Code Online (Sandbox Code Playgroud)


arh*_*aco 43

我有另一个使用微秒(UNIX,POSIX等)的工作示例.

    #include <sys/time.h>
    typedef unsigned long long timestamp_t;

    static timestamp_t
    get_timestamp ()
    {
      struct timeval now;
      gettimeofday (&now, NULL);
      return  now.tv_usec + (timestamp_t)now.tv_sec * 1000000;
    }

    ...
    timestamp_t t0 = get_timestamp();
    // Process
    timestamp_t t1 = get_timestamp();

    double secs = (t1 - t0) / 1000000.0L;
Run Code Online (Sandbox Code Playgroud)

这是我们编码的文件:

https://github.com/arhuaco/junkcode/blob/master/emqbit-bench/bench.c

  • 你应该在你的例子的开头添加```#include <sys/time.h>```. (5认同)

gon*_*aao 36

这是C++ 11中的一个简单解决方案,它为您提供令人满意的解决方案.

#include <iostream>
#include <chrono>

class Timer
{
public:
    Timer() : beg_(clock_::now()) {}
    void reset() { beg_ = clock_::now(); }
    double elapsed() const { 
        return std::chrono::duration_cast<second_>
            (clock_::now() - beg_).count(); }

private:
    typedef std::chrono::high_resolution_clock clock_;
    typedef std::chrono::duration<double, std::ratio<1> > second_;
    std::chrono::time_point<clock_> beg_;
};
Run Code Online (Sandbox Code Playgroud)

或者在*nix上,对于c ++ 03

#include <iostream>
#include <ctime>

class Timer
{
public:
    Timer() { clock_gettime(CLOCK_REALTIME, &beg_); }

    double elapsed() {
        clock_gettime(CLOCK_REALTIME, &end_);
        return end_.tv_sec - beg_.tv_sec +
            (end_.tv_nsec - beg_.tv_nsec) / 1000000000.;
    }

    void reset() { clock_gettime(CLOCK_REALTIME, &beg_); }

private:
    timespec beg_, end_;
};
Run Code Online (Sandbox Code Playgroud)

以下是示例用法:

int main()
{
    Timer tmr;
    double t = tmr.elapsed();
    std::cout << t << std::endl;

    tmr.reset();
    t = tmr.elapsed();
    std::cout << t << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

来自https://gist.github.com/gongzhitaao/7062087


Tom*_*rle 18

#include <boost/progress.hpp>

using namespace boost;

int main (int argc, const char * argv[])
{
  progress_timer timer;

  // do stuff, preferably in a 100x loop to make it take longer.

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

progress_timer超出范围时,它会打印出来自创建以来经过的时间.

更新:我做了一个简单的独立替代(OSX/iOS但易于移植):https://github.com/catnapgames/TestTimerScoped

  • @meowsqueak嗯,auto_cpu_timer似乎需要链接Boost系统库,因此它不再是仅限标头的解决方案.太糟糕了......突然之间让其他选择更具吸引力. (3认同)
  • 这有效,但请注意,progress_timer已被弃用(在boost 1.50之前的某个时间) - auto_cpu_timer可能更合适. (2认同)

Cap*_*mic 5

Windows提供了QueryPerformanceCounter()函数,Unix有gettimeofday()两个函数可以测量至少1微秒的差异.

  • *相同的编译源*听起来像你想在两个系统上运行相同的二进制文件,似乎并非如此.如果你的意思是*相同的来源*然后一个`#ifdef`必须是好的(它是从你接受的答案判断),然后我没有看到问题:`#ifdef WIN32 #include <windows.h > ... #else ...#endif`. (4认同)
  • 然后寻找一些包装库http://stackoverflow.com/questions/1487695/c-cross-platform-high-resolution-timer (2认同)