【问题标题】:Calculate time to execute a function计算执行函数的时间
【发布时间】:2015-07-19 19:17:11
【问题描述】:

我需要计算一个函数的执行时间。

目前,我使用 time.h

函数开头:

time_t tbegin,tend;
double texec=0.000;
time(&tbegin);

返回前:

 time(&tend);
 texec = difftime(tend,tbegin);

它工作正常,但在 texec 中以整数形式给我一个结果。

我怎样才能获得以毫秒为单位的执行时间?

【问题讨论】:

  • 阅读std::chrono,但要注意不同操作系统上的计时问题。例如,Windows 喜欢以 15.625 毫秒为增量提供时间。

标签: c++ time time.h


【解决方案1】:

大多数简单程序的计算时间都以毫秒为单位。所以,我想,你会发现这很有用。

#include <time.h>
#include <stdio.h>

int main() {
    clock_t start = clock();
    // Executable code
    clock_t stop = clock();

    double elapsed = (double)(stop - start) * 1000.0 / CLOCKS_PER_SEC;
    printf("Time elapsed in ms: %f\n", elapsed);
}

如果您想计算整个程序的运行时间并且您在 Unix 系统上,请使用 time 命令运行您的程序,如下所示:time ./a.out

【讨论】:

【解决方案2】:

您可以在 C++14 中使用带有 auto 参数的 lambda 来为其他函数计时。您可以将定时函数的参数传递给您的 lambda。我会这样做:

// Timing in C++14 with auto lambda parameters

#include <iostream>
#include <chrono>

// need C++14 for auto lambda parameters
auto timing = [](auto && F, auto && ... params)
{
    auto start = std::chrono::steady_clock::now();
    std::forward<decltype(F)>(F)
    (std::forward<decltype(params)>(params)...); // execute the function
    return std::chrono::duration_cast<std::chrono::milliseconds>(
               std::chrono::steady_clock::now() - start).count();
};

void f(std::size_t numsteps) // we'll measure how long this function runs
{
    // need volatile, otherwise the compiler optimizes the loop
    for (volatile std::size_t i = 0; i < numsteps; ++i);
}

int main()
{
    auto taken = timing(f, 500'000'000); // measure the time taken to run f()
    std::cout << "Took " << taken << " milliseconds" << std::endl;

    taken = timing(f, 100'000'000); // measure again
    std::cout << "Took " << taken << " milliseconds" << std::endl;
}

优点是您可以将任何可调用对象传递给timing lambda。

但如果你想保持简单,你可以这样做:

auto start = std::chrono::steady_clock::now();
your_function_call_here();
auto end = std::chrono::steady_clock::now();
auto taken = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << taken << " milliseconds";

如果您知道在运行期间不会更改系统时间,则可以改用std::chrono::high_resolution_clock,这可能更准确。但是std::chrono::steady_clock 在运行期间对系统时间变化不敏感。

PS:如果需要对成员函数计时,可以这样做:

// time member functions
template<class Return, class Object, class... Params1, class... Params2>
auto timing(Return (Object::*fp)(Params1...), Params2... params)
{
    auto start = std::chrono::steady_clock::now();
    (Object{}.*fp)(std::forward<decltype(params)>(params)...);
    return std::chrono::duration_cast<std::chrono::milliseconds>(
               std::chrono::steady_clock::now() - start).count();
};

然后将其用作

// measure the time taken to run X::f()
auto taken = timing(&X::f, 500'000'000);
std::cout << "Took " << taken << " milliseconds" << std::endl;

到时间,例如X::f() 成员函数。

【讨论】:

  • 如何为函数方法执行此操作,当我传递计时(Object.Method1)时,它返回错误“非标准语法;使用'&'创建指向成员的指针”
  • @RobinAtTech 您可以使用std::bind,例如using namespace std::placeholders; X x; auto f = std::bind(&amp;X::f, &amp;x, _1);,请在此处查看完整示例:coliru.stacked-crooked.com/a/d4b75548ec9b5154
【解决方案3】:

你可以创建这样的函数source:

typedef unsigned long long timestamp_t;

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

那么你就可以用它来获取时差了。

timestamp_t time1 = get_timestamp();
// Your function
timestamp_t time2 = get_timestamp();

对于windows你可以使用这个函数:

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

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. */

int64 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
}

Source

【讨论】:

【解决方案4】:

在标题&lt;chrono&gt; 中有一个 班级std::chrono::high_resolution_clock
那就是你想要的。不过使用起来有点麻烦;

#include <chrono>
using namespace std;
using namespace chrono;

auto t1 = high_resolution_clock::now();
// do calculation here
auto t2 = high_resolution_clock::now();
auto diff = duration_cast<duration<double>>(t2 - t1); 
// now elapsed time, in seconds, as a double can be found in diff.count()
long ms = (long)(1000*diff.count());

【讨论】:

    猜你喜欢
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 2020-03-28
    相关资源
    最近更新 更多