我正在尝试优化函数的用法,以检查数字是否为素数。
我写了以下函数:
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;
}
但是,在执行while
循环之前,我想检查一个数字是否已经通过我的isPrime函数传递,这样我就可以返回它是否是素数而不必执行{{ 1}}循环。
注意,我想在不使用全局变量或不扩展while
的情况下执行此操作。
答案 0 :(得分:3)
var isPrime = (function () {
var checked_numbers = [];
function isPrime(num) { ... }
return isPrime;
}();
对于返回的checked_numbers
函数, isPrime
在范围中是(可以在IIFE外部访问,因为它(函数本身)被分配给全局变量),但是IIFE之外的任何东西都无法触及它。
答案 1 :(得分:3)
您可以使用Memoization技术。
Memoization是一种编程技术,它试图通过缓存以前计算的结果来提高函数的性能。
基本思想是我们构建一个空对象然后添加Keys作为哈希值或参数值,然后如果我们得到一个已经在Object键上可用的参数,那么我们返回该键的Object值。
以下功能有几种变体,但是这个功能比其他实现要好得多。从Addy Osmani文章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);
};
}
<强>用法:强>
var cachedIsPrime = memoize(isPrime);
var isPrime = cachedIsPrime(2);
isPrime = cachedIsPrime(3);
然后你可以传递需要记忆的功能。
OP注意: 对于具有单个参数的上述上下文,如下所示的简单memoize函数可以工作:
var memoize = function(passedFunc) {
var cache = {};
return function(x) {
if (x in cache) return cache[x];
return cache[x] = passedFunc(x);
};
};
答案 2 :(得分:1)
您要找的是 memoization 模式。
来自Wikipedia:
在计算中, memoization 是一种优化技术 主要用于通过存储结果来加速计算机程序 昂贵的函数调用并返回缓存的结果时相同 输入再次发生。
您可以编写your own memoize
function(根据其他答案的建议),也可以使用npm上提供的众多优化和经过良好测试的实现之一,例如fast-memoize.js或memoizee。如果您已经使用Lodash,它也有自己的_.memoize功能。
示例:
var isPrime = memoize(/* your function */)
isPrime(2) // => true
isPrime(2) // => true (from the cache)