2017-02-16 8 views
2

私は、数値が素数であるかどうかをチェックする関数の使用法を最適化しようとしています。私はそれかどうかを返すことができるように、私のwhileループの実行は、私は、数はすでに私のisPrime機能を通過したかどうかを確認したいの前に、しかしグローバル変数を使用しないでJavaScriptでキャッシュする

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ループを実行しなくても素数です。

グローバル変数を使用せずに、またはObject.prototypeを拡張せずにこれを実行したいとします。

+0

注意ループのヘッダーから 'Math.sqrt()'コールを取る*以上のものが必要です。とにかく、seiveは効果的にキャッシュの目的に役立ちます。 – Pointy

+0

seiveはキャッシュの目的としてどのように機能しますか? – nashcheez

+0

セイバー*はすべての数値のマップ(計算量の限度まで)であり、その数値が素数かどうかを示すフラグです。 – Pointy

答えて

3

Memoizationのテクニックを使用できます。

Memoizationは、以前に計算された結果をキャッシュすることによって機能のパフォーマンスを向上させるプログラミング手法です。

基本的な考え方は、空のObjectを作成してから、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); 
    }; 
}; 
1

あなたが探しているのはメモパターンです。 Wikipediaから

:計算に

メモ化は場合同じ 入力を 高価な関数呼び出しの結果を格納し、キャッシュされた結果を返すことによって、コンピュータプログラムをスピードアップするために主に使用される最適化技術 あります再び発生する。

あなたはyour own memoize functionを書くことができます(他の回答により示唆されるように)、またはあなたがfast-memoize.jsまたはmemoizeeなどのNPMで利用できる多くの最適化十分にテストされた実装、のいずれかを使用することができます。既にLodashを使用している場合は、独自の_.memoize機能も備えています。

例:

var isPrime = memoize(/* your function */) 

isPrime(2) // => true 
isPrime(2) // => true (from the cache) 
3

closureを作成するためにIIFE内の変数を宣言します。

var isPrime = (function() { 
    var checked_numbers = []; 

    function isPrime(num) { ... } 

    return isPrime; 
}(); 

checked_numbers(それ(関数自体)は、グローバル変数に割り当てられているため、生命維持外部アクセス可能である)が返さisPrime関数のスコープでであるが、生命維持外何もそれに触れることができません。

関連する問題