Last active
December 8, 2019 23:26
-
-
Save neilmayhew/67cc93817ef55f168b7282500d10208e to your computer and use it in GitHub Desktop.
Fibonacci face-off
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function domsFib(number) { | |
let time = new Date(); | |
let sequence = [1,1] | |
for (let i = 2; i<number; i++) { | |
let index = (i-1)%2; | |
sequence[index] = sequence[0] + sequence[1]; | |
} | |
if (number%2) return sequence[1] | |
else return sequence[0] | |
} | |
function dadsFib(number) { | |
let prev2 = 1; | |
let sum = 1; | |
for (let i = 2; i < number; i++) { | |
let prev1 = sum; | |
sum += prev2; | |
prev2 = prev1; | |
} | |
return sum; | |
} | |
const dumbFib = number => number < 3 ? 1 : dumbFib(number-1) + dumbFib(number-2); | |
function memoize(func) { | |
let cache = []; | |
return x => x in cache ? cache[x] : cache[x] = func(x); | |
} | |
let memoFib = memoize(number => number < 3 ? 1 : memoFib(number-1) + memoFib(number-2)); | |
// memoFib.name = "memoFib"; // Doesn't work, not sure why | |
const oneOffMemoFib = number => { | |
let fib = memoize(number => number < 3 ? 1 : fib(number-1) + fib(number-2)); | |
return fib(number); | |
} | |
let funcs = [domsFib, dadsFib, memoFib, oneOffMemoFib].map(func => | |
({ name: func.name || "memoFib", func }) | |
); | |
const testResults = (funcs, number) => { | |
funcs.forEach(({name, func}) => { | |
console.log(`Result for ${name}: ${func(number)}`); | |
}); | |
if (!funcs.every(({func}) => func(number) == funcs[0].func(number))) { | |
console.log("Note: the results differ"); | |
} | |
} | |
const benchmark = (func, arg, repetitions) => { | |
let startTime = new Date(); | |
for (let i = 0; i < repetitions; i++) { | |
func(arg); | |
} | |
return (new Date() - startTime) / repetitions; | |
} | |
const testEfficiency = (funcs, number, repetitions) => { | |
let elapsed = funcs.map(({name, func}) => | |
({ name, time: benchmark(func, number, repetitions) }) | |
); | |
elapsed.forEach(({name, time}) => { | |
const ratio = (time / elapsed[0].time).toFixed(4); | |
console.log(`Running time for ${name}: ${time} = ${ratio}x ${elapsed[0].name}`); | |
}); | |
} | |
let useDumb = process.argv.includes("dumb"); | |
const number = useDumb ? 30 : 60; | |
const reps = useDumb ? 1000 : 1000000; | |
if (useDumb) funcs.push({name:"dumbFib", func:dumbFib}); | |
testResults(funcs, number); | |
testEfficiency(funcs, number, reps); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To run this in NodeJS with
useDumb
set to true, append the word "dumb" to the end of the command line.