使用标准库函数
clock()
是衡量C中函数调用执行时间的几种方法之一。因此,例如,可以按如下方式比较两个函数(具有不同原型)的执行时间:
#include <stdio.h>
#include <time.h>
int f(int n) { return n < 3 ? 1 : f(n-1) + f(n-2); }
int g(int n, int a, int b) { return n < 3 ? b : g(n-1, b, a+b); }
int main(void) {
double start, elapsed1, elapsed2;
printf("n f g\n");
for(int n = 30; n <= 40; n++) {
start = (double) clock();
f(n);
elapsed1 = (clock() - start) / CLOCKS_PER_SEC;
start = (double) clock();
g(n, 1, 1);
elapsed2 = ((double) clock() - start) / CLOCKS_PER_SEC;
printf("%d %.1f %.1f\n", n, elapsed1, elapsed2);
}
return 0;
}
为了使这段代码更简洁,我们可以定义一个类似函数的宏(因为在 C 中没有“通用函数”指针):
#include <stdio.h>
#include <time.h>
double START, ELAPSED;
#define CPUTIME(FCALL) (START = (double) clock(), FCALL, ELAPSED = ((double) clock() - START) / CLOCKS_PER_SEC)
int f(int n) { return n < 3 ? 1 : f(n-1) + f(n-2); }
int g(int n, int a, int b) { return n < 3 ? b : g(n-1,b,a+b); }
int main(void) {
printf("n f g\n");
for(int n = 30; n <= 40; n++)
printf("%d %.1f %.1f\n", n, CPUTIME(f(n)), CPUTIME(g(n, 1, 1)) );
return 0;
}
问题: 有没有办法让变量 START 和 ELAPSED 局部于宏定义,这样宏仍然可以作为非空“函数”调用?有没有更好的方法让代码更简洁,不用宏定义?
您可以使用非标准的statement-expression C扩展 (至少在 clang、gcc 和 tinycc 中可用)。
#include <stdio.h>
#include <time.h>
#define CPUTIME(FCALL) ({ double START = clock(); FCALL; ((double) clock() - START) / CLOCKS_PER_SEC; })
int f(int n) { return n < 3 ? 1 : f(n-1) + f(n-2); }
int g(int n, int a, int b) { return n < 3 ? b : g(n-1,b,a+b); }
int main(void) {
printf("n f g\n");
for(int n = 30; n <= 40; n++)
printf("%d %.1f %.1f\n", n, CPUTIME(f(n)), CPUTIME(g(n, 1, 1)) );
return 0;
}
这是一个带括号的块,它的计算结果是其中最后一条语句的计算结果。
我认为标准 C 中没有可以满足您的 API 约束的通用解决方案。如果您追求标准 c 线程安全和/或稍微好一点的代码生成,您可以使用您的原始解决方案并(重新)在调用宏的块中本地声明变量。