使用类似函数的宏测量 C 中函数调用的执行时间

问题描述 投票:0回答:1

使用标准库函数

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 局部于宏定义,这样宏仍然可以作为非空“函数”调用?有没有更好的方法让代码更简洁,不用宏定义?

c macros execution-time
1个回答
1
投票

您可以使用非标准的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 线程安全和/或稍微好一点的代码生成,您可以使用您的原始解决方案并(重新)在调用宏的块中本地声明变量。

© www.soinside.com 2019 - 2024. All rights reserved.