/* * Program to compare performance of various ways of computing * an element of the Fibonacci sequence: iterative, recursive, * and recursive with memoization. * * This version makes the array for memoization an additional * parameter to the function. */ #include #include #include /* for get_time */ double get_time(); long long fibonacci_iterate(int n); long long fibonacci_recurse(int n, long long *count); long long fibonacci_recurse_m(int n, long long *count, long long saved[]); int main(void) { int n; printf("which index?\n"); if ((scanf("%d", &n) != 1) || (n < 0)) { printf("input must be a non-negative integer\n"); return 1; } double start_time, end_time; long long result; long long count; printf("computing fibonacci(%d)\n", n); start_time = get_time(); result = fibonacci_iterate(n); end_time = get_time(); puts("\niterative version:"); printf("result %lld (time %.8f seconds)\n", result, end_time - start_time); start_time = get_time(); count = 0; result = fibonacci_recurse(n, &count); end_time = get_time(); puts("\nrecursive version:"); printf("result %lld (time %.8f seconds, count %lld)\n", result, end_time - start_time, count); start_time = get_time(); long long save[n+1]; for (int i = 0; i < n+1; ++i) { save[i] = 0; } count = 0; result = fibonacci_recurse_m(n, &count, save); end_time = get_time(); puts("\nmemoized recursive version:"); printf("result %lld (time %.8f seconds, count %lld)\n", result, end_time - start_time, count); return 0; } /* * compute the n-th fibonacci number using iteration */ long long fibonacci_iterate(int n) { /* * for n == 0, 1 * for n == 1, 1 * otherwise fibonacci(n-1) + fibonacci(n-2) */ if (n <= 1) { return 1; } else { /* * i is main loop variable * one_before is fibonacci(i-1) * two_before is fibonacci(i-2) */ int i = 2; long long one_before = 1; long long two_before = 1; long long current; for ( ; i <= n; ++i) { current = one_before + two_before; two_before = one_before; one_before = current; } return current; } } /* * compute the n-th fibonacci number using recursion (naive version) */ long long fibonacci_recurse(int n, long long *count) { (*count)+=1; if (n <= 1) { return 1; } else { return fibonacci_recurse(n-1, count) + fibonacci_recurse(n-2, count); } } /* * compute the n-th fibonacci number using recursion (version using * memoization) */ long long fibonacci_recurse_m(int n, long long *count, long long save[]) { (*count)+=1; if (save[n] != 0) { return save[n]; } else { long long result; if (n <= 1) { result = 1; } else { result = fibonacci_recurse_m(n-1, count, save) + fibonacci_recurse_m(n-2, count, save); } save[n] = result; return result; } } /* * get time in seconds since "epoch" * uses Linux library function gettimeofday, so probably not portable */ double get_time() { struct timeval tv; if (gettimeofday(&tv, NULL) == 0) return (double) tv.tv_sec + ((double) tv.tv_usec / (double) 1000000); else return 0.0; }