Using the standard library function clock()
is one of several methods to measure the execution time of a function call in C. So, for example, the comparison of the execution times of two functions (with different prototypes) can be done as follows:
#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;
}
To make this code more concise, we could define a function-like macro (since there is no "generic function" pointer in 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;
}
Questions: Is there a way to make variables START and ELAPSED local to the macro definition so that the macro can still be called as a non-void "function"? Is there a better way to make the code more concise, without using a macro definition?
You can use the nonstandard statement-expression C extension (available in at least clang, gcc, and 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;
}
It's a parenthesized block that's evaluated to what the last statement in it evaluates to.
I don't think there's a generic solution within standard C that would satisfy your API constraints. If you're after standard-c-only threadsafety and/or slightly better codegen, you could use your original solution and (re)declare the variable(s) locally within the block that calls the macro.