|
#include <stdlib.h> |
|
#include <stdio.h> |
|
#include <time.h> |
|
|
|
int fibI(int n) { |
|
int result = 0; |
|
int a = 0; |
|
int b = 1; |
|
for (int i = 2; i <= n; i++) { |
|
result = a + b; |
|
a = b; |
|
b = result; |
|
} |
|
return result; |
|
} |
|
|
|
int fibM(int n, int *memo) { |
|
if (n < 2) { |
|
return n; |
|
} |
|
if (memo[n - 1] != 0) { |
|
return memo[n - 1]; |
|
} |
|
int result = fibM(n - 1, memo) + fibM(n - 2, memo); |
|
memo[n - 1] = result; |
|
return result; |
|
} |
|
|
|
int fibR(int n) { |
|
if (n < 2) { |
|
return n; |
|
} |
|
return fibR(n - 1) + fibR(n - 2); |
|
} |
|
|
|
void bench(int n, char *desc, int (*fn)(int), int arg) { |
|
printf("Benchmarking %s\n", desc); |
|
|
|
int64_t *results = (int64_t*)malloc(n*sizeof(int64_t)); |
|
struct timespec start, end; |
|
u_int64_t before_ns, after_ns; |
|
|
|
for (int i = 0; i < n; i++) { |
|
clock_gettime(CLOCK_MONOTONIC, &start); |
|
fn(arg); |
|
clock_gettime(CLOCK_MONOTONIC, &end); |
|
|
|
before_ns = (start.tv_sec * 1000000000LL) + start.tv_nsec; |
|
after_ns = (end.tv_sec * 1000000000LL) + end.tv_nsec; |
|
results[i] = after_ns - before_ns; |
|
} |
|
|
|
int64_t sum = 0; |
|
for (int i = 0; i < n; i++) { |
|
sum += results[i]; |
|
} |
|
double avg = sum / n; |
|
printf("Average time: %.2fns\n", avg); |
|
free(results); |
|
} |
|
|
|
int fib_memo(int n) { |
|
int *memo = (int*)calloc(n, sizeof(int)); |
|
int result = fibM(n, memo); |
|
free(memo); |
|
return result; |
|
} |
|
|
|
int main(int argc, char **argv) { |
|
int n = 1000000; |
|
int num = 40; |
|
|
|
// bench(n, "recursive fib", fibR, num); |
|
bench(n, "iterative fib", fibI, num); |
|
bench(n, "memoized fib", fib_memo, num); |
|
|
|
return 0; |
|
} |
better impl in Go: