【问题标题】:Elapsed time of running a C program运行 C 程序的已用时间
【发布时间】:2011-02-05 04:33:30
【问题描述】:

我想知道将哪些 C 代码行添加到程序中,以便它告诉我程序运行所需的总时间。我猜应该在 main 开始附近和 main 函数结束后有一个计数器初始化。是正确的标题clock.h吗?

非常感谢...

更新我有一台 Win Xp 机器。是否只是在程序开头添加clock() 并在程序末尾添加另一个clock()?然后我可以估计时间差。是的,没错,它是time.h。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <share.h>
#include <time.h>


void f(long double fb[], long double fA, long double fB);

int main() {

clock_t start, end;
start = clock();


const int ARRAY_SIZE = 11;

long double* z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);

int i;
long double A, B;

if (z == NULL) {
    printf("Out of memory\n");
    exit(-1);
}

A = 0.5;
B = 2;


for (i = 0; i < ARRAY_SIZE; i++) {
    z[i] = 0;
}

z[1] = 5;

f(z, A, B);

for (i = 0; i < ARRAY_SIZE; i++)
    printf("z is %.16Le\n", z[i]);



free(z);
z = NULL;

end = clock();
printf("Took %ld ticks\n", end-start);
printf("Took %f seconds\n", (double)(end-start)/CLOCKS_PER_SEC);



return 0;  
}  

void f(long double fb[], long double fA, long double fB) {
    fb[0] = fb[1]* fA;
    fb[1] = fb[1] - 1;
    return;
 }  

MVS2008 的一些错误:

testim.c(16):错误 C2143:语法错误:缺少“;”在“常量”之前 testim.c(18) :error C2143: 语法错误: 缺少';'在“类型”之前 testim.c(20) :error C2143: 语法错误: 缺少';'在“类型”之前 testim.c(21) :error C2143: 语法错误: 缺少';'在“类型”之前 testim.c(23) :error C2065: 'z' : undeclared identifier testim.c(23) :warning C4047: '==' : 'int' 与 'void *' 的间接级别不同 testim.c(28):错误 C2065:'A':未声明的标识符 testim.c(28) : 警告 C4244: '=' : 从 'double' 转换为 'int',可能丢失数据

它会出现 28 个错误。请注意,如果没有您的时钟代码,我没有任何错误/警告。

最新消息:很遗憾,我在这里没有得到好的答复。但在谷歌上搜索后,代码是有效的。这里是:

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


void f(long double fb[], long double fA);

int main() {

clock_t start = clock();


const int ARRAY_SIZE = 11;

long double* z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);

int i;
long double A;

if (z == NULL) {
printf("Out of memory\n");
exit(-1);
}

A = 0.5;


for (i = 0; i < ARRAY_SIZE; i++) {
z[i] = 0;
}

z[1] = 5;

f(z, A);

for (i = 0; i < ARRAY_SIZE; i++)
printf("z is %.16Le\n", z[i]);



free(z);
z = NULL;

printf("Took %f seconds\n", ((double)clock()-start)/CLOCKS_PER_SEC);



return 0;
}

void f(long double fb[], long double fA) {
fb[0] = fb[1]* fA;
fb[1] = fb[1] - 1;
return;
}

干杯

4 月 10 日更新:感谢“JustJeff”,这是一个更好的解决方案

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

void f(long double fb[], long double fA);

const int ARRAY_SIZE = 11;

int main(void)
{

   long double* z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);
   int i;
   long double A;

   LARGE_INTEGER freq;
   LARGE_INTEGER t0, tF, tDiff;
   double elapsedTime;
   double resolution;

   if (z == NULL) {
   printf("Out of memory\n");
   exit(-1);
   }
   QueryPerformanceFrequency(&freq);
   QueryPerformanceCounter(&t0);
   // code to be timed goes HERE
   {
    A = 0.5;


    for (i = 0; i < ARRAY_SIZE; i++) {
    z[i] = 0;
    }

    z[1] = 5;
    f(z, A);


    for (i = 0; i < ARRAY_SIZE; i++)
    printf("z is %.16Le\n", z[i]);

    free(z);
    z = NULL;

   }
QueryPerformanceCounter(&tF);
tDiff.QuadPart = tF.QuadPart - t0.QuadPart;
elapsedTime = tDiff.QuadPart / (double) freq.QuadPart;
resolution = 1.0 / (double) freq.QuadPart;
printf("Your performance counter ticks %I64u times per second\n", freq.QuadPart);
printf("Resolution is %lf nanoseconds\n", resolution*1e9);
printf("Code under test took %lf sec\n", elapsedTime);
return 0;
}


void f(long double fb[], long double fA) {
fb[0] = fb[1]* fA;
fb[1] = fb[1] - 1;
return;
}

它适用于 MVS2008 和 2003 年的 Borland C++ builderX。

【问题讨论】:

  • 如果您觉得自己现在拥有最佳答案,您可以发布答案并接受它。这样做可能有助于其他人寻找手头问题的答案(我相信其他人一直在寻找这个问题)。
  • 我不知道我是否有正确的答案。但它正在工作。我总是欢迎建设性的建议,因为我还在学习。我可以接受(打勾)我自己的答案吗?
  • 是的,你可以。顺便说一句,不要故意粗鲁,但你怎么没有在这里得到好的答复?你有几个很好的答案,应该可以。如果您遇到错误,那是您自己的代码,而不是回答者给您的代码。如果您认为您得到的答案不好,请说明我们如何改进它们。
  • 我用 MVS2008 测试了这里的建议,正如我在帖子中提到的那样,我遇到了错误。我是 C 编程的新手。我不能说为什么这里建议的代码不起作用。我从谷歌得到了答案,用我的代码对其进行了测试,它似乎正在工作。随着我随着时间的推移提高我对 C 的知识,我可以有一天回来并指出这里建议的代码中的任何错误。我自己的代码可能有一些东西。我还不知道这个。我是来学习和分享知识的。由于我在 C 方面的知识有限,我很难成为信息提供者,但这会改变。

标签: c windows time elapsed


【解决方案1】:

如果您使用的是 Windows,并且想要在微秒内测量数据,请研究 QueryPerformanceCounter() 和 QueryPerformanceFrequency()。在许多系统上,它们可以解析完整的处理器时钟周期,nano秒的三分之一,我不相信我见过它比 3.5795MHz 更粗糙,仍然远低于 1 微秒。

您调用 QueryPerformanceFrequency() 来确定计数器每秒计数的次数。然后在测试代码之前调用 QueryPerformanceCounter(),然后再调用。将 QPC 的两个读数相加并除以 QPF 的周期,就可以得到两个 QPC 调用之间经过的时间。就这样……

LARGE_INTEGER freq;
LARGE_INTEGER t0, tF, tDiff;
double elapsedTime;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&t0);
// code to be timed goes HERE
QueryPerformanceCounter(&tF);
tDiff.QuadPart = tF.QuadPart - t0.QuadPart;
elapsedTime = tDiff.QuadPart / (double) freq.QuadPart;
// elapsedTime now has your measurement, w/resolution given by freq

显然,这些访问硬件计数设备与主板上的某些系统振荡器相关联,在这种情况下,它们不应受到软件负载的抖动影响。您获得的分辨率取决于您的系统。

跟进

这是一个演示界面的非常简单的完整程序:

#include <windows.h>
int main(void)
{
    LARGE_INTEGER freq;
    LARGE_INTEGER t0, tF, tDiff;
    double elapsedTime;
    double resolution;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&t0);
    // code to be timed goes HERE
    {
        Sleep(10);
    }
    QueryPerformanceCounter(&tF);
    tDiff.QuadPart = tF.QuadPart - t0.QuadPart;
    elapsedTime = tDiff.QuadPart / (double) freq.QuadPart;
    resolution = 1.0 / (double) freq.QuadPart;
    printf("Your performance counter ticks %I64u times per second\n", freq.QuadPart);
    printf("Resolution is %lf nanoseconds\n", resolution*1e9);
    printf("Code under test took %lf sec\n", elapsedTime);
    return 0;
}

对于这么简单的事情,跳过 IDE 会更快,只需将其保存在 foo.c 文件中并(假设 MS VS 2008)使用命令行

cl foo.c

构建它。这是我系统上的输出:

Your performance counter ticks 3579545 times per second
Resolution is 279.365115 nanoseconds
Code under test took 0.012519 sec

【讨论】:

  • 谢谢。这对我来说似乎有点太高级了:)。
  • 调用真的很简单,使用方式和clock()一样,分辨率比clock()好很多,最差的是64位整数.好吧,它也是特定于窗口的,但您确实标记了窗口。
  • 谢谢。我已经添加了标题 windows.h 但我仍然收到错误。 QueryPerformanceFrequency(&freq); 行出现错误。编译器抱怨: E2293 ) 预期在第 12 行。另一个是:QueryPerformanceCounter(&t0);错误是: E2293 ) 预计在第 13 行。另一个是 tDiff = tF - t0;错误是:E2096 Illegal structure operation in function main 在第 57 行。最后一个错误:elapsedTime = tDiff / (double) freq;错误是:第 58 行的函数 main 中的 E2110 类型转换不兼容。我使用 Borland C++ BuilderX 编译了它。有什么建议吗?
  • 获取 microsoft visual studio express 2005 或 2008,它们是免费的,非常适合 Windows 工作。
  • 不确定您使用的 Borland 编译器有多旧,可能有一种方法可以让您巧妙地使用它,但它确实适用于 MS VS Express 2008,我相信 2005 版一样的。
【解决方案2】:

你也可以试试GetTickCount。时钟也可以正常工作。但是,我猜如果某个其他进程或某个手动更改系统时间,时钟值会发生变化,而 GetTickCount 值不受此影响。

【讨论】:

  • 是的,这是另一种选择。我会调查此事。
【解决方案3】:

在 Unix(我认为)系统上,将程序名称作为命令行参数的 time 命令将告诉您程序运行所需的时间。请注意,这测量了整个程序的执行时间。如果您只需要测试一个部分,请包含time.h 并使用时钟功能,或多或少像这样:

#include <time.h>

int main() {
    clock_t start;
    clock_t end;
    int function_time;
    start = clock();
    function_you_want_to_time();
    end = clock();
    /* Get time in milliseconds */
    function_time = (double)(end - start) / (CLOCKS_PER_SEC / 1000.0);
    return 0;
}

这将为您提供以毫秒为单位的时间(注意 / 1000.0 部分)。如果你想要秒,删除/ 1000.0。如果您想要更准确的普通时钟滴答,请将function_time 设为clock_t 并将function_time = ... 行替换为:

function_time = end - start;

要对整个程序进行计时,我建议创建一个名为 _main() 的函数,将所有与程序相关的代码从 main()(不是计时代码!)移动到该函数,然后从 main() 调用它.这样一来,更清楚什么是时序代码,以及程序的其余部分是什么。

【讨论】:

  • 这样做的一个缺点是,例如,如果您只想为某事的实际计算部分计时,并且不想包括资源/数据加载时间或输出时间等,@ 987654333@ 命令不能这样做(因为它会计时整个执行)。
  • 确实如此。显然clock() 函数对此更好,但我不知道。我补充一句。
  • 顺便说一句,如果您想为整个程序计时,请将 clock() 调用放在开头和结尾。另外,谁能告诉我除以CLOCKS_PER_SEC是否正确?
  • 谢谢。 function_you_want_to_time() 是否必须接受参数?我想为整个节目计时。
  • @yCalleecharan:如果你想为整个程序计时,就像我说的,用程序的其余部分替换 function_you_want_to_time(); 行。函数是否接受参数并不重要。如果您想非常小心地测量,请将 main() 中的所有内容移动到另一个函数并从 main() 调用它。这样您就不会在开始计时之前声明变量。对于 C99 或 C++,这不适用-
【解决方案4】:

如果您想测试代码块,您可以使用clock() 函数(在&lt;time.h&gt; 中),或*nix 上的time 程序,正如另一个回答者建议的那样。例如

> time ./foo my args

对于时钟,您需要减去两个检查点之间的差。例如

#include <time.h>

void f() {
  clock_t start, end;

  start = clock();

  // some long code.

  end = clock();
  printf("Took %ld ticks\n", end-start);
  // or in (fractional) seconds.
  printf("Took %f seconds\n", (double)(end-start)/CLOCKS_PER_SEC);
}

更新

关于您的新错误,您不能在 VC 中混合使用代码和声明。你不能调用任何函数然后继续声明变量。在顶部声明所有变量,或使用 C++ 模式编译。

【讨论】:

  • 我收到很多错误。我们必须定义clock_t的类型,开始吗?
  • 我们需要 void f() 吗?或者我们可以把clock_t start, end; start = clock();...end = clock();printf("花费了 %ld 个滴答声\n", end-start);在主里面?
  • 对不起,这对我不起作用。 MVS208 愚蠢地抱怨 102 个错误。编译器抱怨很多事情是未定义的。您确定您的代码 sn-p 中没有遗漏任何内容吗?
  • 发布您的代码和错误。 (我想你在 printf 中包含了 ?)
  • 我真的不明白我的程序是怎么出错的。我正在使用 C。当我没有您的时钟代码时,该程序运行良好,没有任何警告。告诉我要在我的代码中修改什么,并让它仍然作为一个 C 程序。谢谢。
【解决方案5】:

如果您的程序需要总计,那么在 Linux 控制台中:

$ time myProgram

您也可以在代码中使用 time.h。

#include <time.h>

int main(){
  time_t start, end;
  start = time(0);

  /* some working code */

  end = time(0);
  printf("%i seconds", end - start );
}

【讨论】:

  • 我收到很多错误。我们是否必须定义time_t的类型,开始?
  • 我认为也可以是int。我不必在我的 Ubuntu 中的任何地方定义它。
【解决方案6】:

您可能需要 time.h 和 clock() 函数。

【讨论】:

    猜你喜欢
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    • 2019-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多