<script src="https://www.jsdelivr.com/package/npm/memoizee"></script>
const fibonacci = (n) => {
if (n <= 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
};
fibonacci(20);
const memoize = function(func) {
var stringifyJson = JSON.stringify,
cache = {};
var cachedfun = function() {
var hash = stringifyJson(arguments);
return hash in cache ? cache[hash] : (cache[hash] = func.apply(this, arguments));
};
cachedfun.__cache = function() {
cache.remove ||
(cache.remove = function() {
var hash = stringifyJson(arguments);
return delete cache[hash];
});
return cache;
}.call(this);
return cachedfun;
};
const fibonacci = memoize((n) => {
if (n <= 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
});
fibonacci(20);
const memoize = function(func) {
const cache= {}
return (args) => {
const n = args[0]
if (n in cache) {
return cache[n];
} else {
const result = func(n)
cache[n] = result
return result
}
}
};
const fibonacci = memoize((n) => {
if (n <= 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
});
fibonacci(20);
//
// Main
//
function memoize (fn, options) {
var cache = options && options.cache
? options.cache
: cacheDefault
var serializer = options && options.serializer
? options.serializer
: serializerDefault
var strategy = options && options.strategy
? options.strategy
: strategyDefault
return strategy(fn, {
cache: cache,
serializer: serializer
})
}
//
// Strategy
//
function isPrimitive (value) {
return value == null || typeof value === 'number' || typeof value === 'boolean' // || typeof value === "string" 'unsafe' primitive for our needs
}
function monadic (fn, cache, serializer, arg) {
var cacheKey = isPrimitive(arg) ? arg : serializer(arg)
var computedValue = cache.get(cacheKey)
if (typeof computedValue === 'undefined') {
computedValue = fn.call(this, arg)
cache.set(cacheKey, computedValue)
}
return computedValue
}
function variadic (fn, cache, serializer) {
var args = Array.prototype.slice.call(arguments, 3)
var cacheKey = serializer(args)
var computedValue = cache.get(cacheKey)
if (typeof computedValue === 'undefined') {
computedValue = fn.apply(this, args)
cache.set(cacheKey, computedValue)
}
return computedValue
}
function assemble (fn, context, strategy, cache, serialize) {
return strategy.bind(
context,
fn,
cache,
serialize
)
}
function strategyDefault (fn, options) {
var strategy = fn.length === 1 ? monadic : variadic
return assemble(
fn,
this,
strategy,
options.cache.create(),
options.serializer
)
}
function strategyVariadic (fn, options) {
var strategy = variadic
return assemble(
fn,
this,
strategy,
options.cache.create(),
options.serializer
)
}
function strategyMonadic (fn, options) {
var strategy = monadic
return assemble(
fn,
this,
strategy,
options.cache.create(),
options.serializer
)
}
//
// Serializer
//
function serializerDefault () {
return JSON.stringify(arguments)
}
//
// Cache
//
function ObjectWithoutPrototypeCache () {
this.cache = Object.create(null)
}
ObjectWithoutPrototypeCache.prototype.has = function (key) {
return (key in this.cache)
}
ObjectWithoutPrototypeCache.prototype.get = function (key) {
return this.cache[key]
}
ObjectWithoutPrototypeCache.prototype.set = function (key, value) {
this.cache[key] = value
}
var cacheDefault = {
create: function create () {
return new ObjectWithoutPrototypeCache()
}
}
const fibonacci = memoize((n) => {
if (n <= 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
});
fibonacci(20);
//
// Main
//
function memoize (fn, options) {
var cache = options && options.cache
? options.cache
: cacheDefault
var serializer = options && options.serializer
? options.serializer
: serializerDefault
var strategy = options && options.strategy
? options.strategy
: strategyDefault
return strategy(fn, {
cache: cache,
serializer: serializer
})
}
//
// Strategy
//
function isPrimitive (value) {
return value == null || typeof value === 'number' || typeof value === 'boolean' // || typeof value === "string" 'unsafe' primitive for our needs
}
function monadic (fn, cache, serializer, arg) {
var cacheKey = isPrimitive(arg) ? arg : serializer(arg)
var computedValue = cache.get(cacheKey)
if (typeof computedValue === 'undefined') {
computedValue = fn.call(this, arg)
cache.set(cacheKey, computedValue)
}
return computedValue
}
function variadic (fn, cache, serializer) {
var args = Array.prototype.slice.call(arguments, 3)
var cacheKey = serializer(args)
var computedValue = cache.get(cacheKey)
if (typeof computedValue === 'undefined') {
computedValue = fn.apply(this, args)
cache.set(cacheKey, computedValue)
}
return computedValue
}
function assemble (fn, context, strategy, cache, serialize) {
return strategy.bind(
context,
fn,
cache,
serialize
)
}
function strategyDefault (fn, options) {
var strategy = fn.length === 1 ? monadic : variadic
return assemble(
fn,
this,
strategy,
options.cache.create(),
options.serializer
)
}
function strategyVariadic (fn, options) {
var strategy = variadic
return assemble(
fn,
this,
strategy,
options.cache.create(),
options.serializer
)
}
function strategyMonadic (fn, options) {
var strategy = monadic
return assemble(
fn,
this,
strategy,
options.cache.create(),
options.serializer
)
}
//
// Serializer
//
function serializerDefault () {
return JSON.stringify(arguments)
}
//
// Cache
//
function ObjectWithoutPrototypeCache () {
this.cache = Object.create(null)
}
ObjectWithoutPrototypeCache.prototype.has = function (key) {
return (key in this.cache)
}
ObjectWithoutPrototypeCache.prototype.get = function (key) {
return this.cache[key]
}
ObjectWithoutPrototypeCache.prototype.set = function (key, value) {
this.cache[key] = value
}
var cacheDefault = {
create: function create () {
return new ObjectWithoutPrototypeCache()
}
}
const fibonacci = memoize((n) => {
if (n <= 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}, {strategy: strategyVariadic});
fibonacci(20);
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Fib Base | |
Fib memoized 1 | |
Fib memoized Tommy | |
Fib fast-memoize | |
Fib fast-memoize with options |
Test name | Executions per second |
---|---|
Fib Base | 8950.8 Ops/sec |
Fib memoized 1 | 46147.7 Ops/sec |
Fib memoized Tommy | 698979.1 Ops/sec |
Fib fast-memoize | 105481.4 Ops/sec |
Fib fast-memoize with options | 19111.3 Ops/sec |
I'll do my best to answer!
Based on the provided benchmark results, it appears that the fast-memoize
strategy with options is the fastest approach for calculating Fibonacci numbers.
Here's a breakdown of the results:
Overall, it seems that using a fast-memoize
strategy with options provides a significant performance boost for calculating Fibonacci numbers.