Reputation: 5183
I am trying to optimise the usage of a function to check whether a number is prime or not.
I have written the following function:
function isPrime(num) {
var start = 2;
// code to check whether num has already been checked for Prime
while(start <= Math.sqrt(num)) {
if (num % start++ < 1) {
return false;
}
}
return num > 1;
}
However, before the execution of my while
loop I want to check if a number already has been passed through my isPrime function, so that I can return whether it is prime or not without having to execute the while
loop.
Note, I want to do this without the usage of a global variable or without extending Object.prototype
.
Upvotes: 3
Views: 2960
Reputation: 9878
You can use the technique of Memoization .
Memoization is a programming technique which attempts to increase a function’s performance by caching its previously computed results.
The basic idea is that we build a empty Object and then add Keys as the hash value or the argument value and then if we get a argument which is already available on the Object keys then we return the Object value for that key.
There are several variation of the below function, but this one performs much better then other implementation. A code Snippet Taken from Addy Osmani article here .
function memoize( fn ) {
return function () {
var args = Array.prototype.slice.call(arguments),
hash = "",
i = args.length;
currentArg = null;
while (i--) {
currentArg = args[i];
hash += (currentArg === Object(currentArg)) ?
JSON.stringify(currentArg) : currentArg;
fn.memoize || (fn.memoize = {});
}
return (hash in fn.memoize) ? fn.memoize[hash] :
fn.memoize[hash] = fn.apply(this, args);
};
}
Usage:
var cachedIsPrime = memoize(isPrime);
var isPrime = cachedIsPrime(2);
isPrime = cachedIsPrime(3);
And then you can pass the function which needs to be Memoized.
OP Notes: For the above context with a single argument, a simple memoize function like the following does work:
var memoize = function(passedFunc) {
var cache = {};
return function(x) {
if (x in cache) return cache[x];
return cache[x] = passedFunc(x);
};
};
Upvotes: 3
Reputation: 21834
What you are looking for is the memoization pattern.
From Wikipedia:
In computing, memoization is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.
You can write your own memoize
function (as suggested by the other answers) or you can use one of the many optimized and well-tested implementations available on npm, like fast-memoize.js or memoizee. If you already use Lodash, it also has its own _.memoize function.
Example:
var isPrime = memoize(/* your function */)
isPrime(2) // => true
isPrime(2) // => true (from the cache)
Upvotes: 1
Reputation: 943157
Declare the variable inside an IIFE to create a closure.
var isPrime = (function () {
var checked_numbers = [];
function isPrime(num) { ... }
return isPrime;
}();
checked_numbers
is in scope for the returned isPrime
function (which is accessible outside the IIFE because it (the function itself) is assigned to a global variable), but nothing outside the IIFE can touch it.
Upvotes: 3