Sunday, May 31, 2015

Memoisation in javascript

Memoization is an optimization technique used primarily to speed up computer programs by keeping the results of expensive function calls and returning the cached result when the same inputs occur again. Memoization has also been used in other contexts (and for purposes other than speed gains), such as in simple mutually recursive descent parsing in a general top-down parsing algorithm that accommodates ambiguity and left recursion in polynomial time and space. Although related to caching, memoization refers to a specific case of this optimization, distinguishing it from forms of caching such as buffering or page replacement. In the context of some logic programming languages, memoization is also known as tabling.

Caching is a useful general technique that sometimes makes programs run faster. It does this by exchanging space for time: Caching tries to save previously computed results in an attempt to reuse them later rather than recomputing them.
Caching is useful in all kinds of situations, including, almost any kind of searching (cache the results of the search so that you can skip it next time), HTML generation (cache the results of the generation process so that you don't have to generate the page next time), and numeric computation (cache the results of the computation).

Lets take an example of recursive function, Fibonacci series
In the following example, the original Fibonacci function is rewritten to include memoization. In the example, a self-executing anonymous function returns an inner function, inner(), which is used as the Fibonacci function. When inner() is returned, its closure allows it to continue to access the “memo” object, which stores all of its previous results. Each time inner() is executed, it first checks to see if a result exists for the current value of “n”. If it does, then the cached value is returned. Otherwise, the original Fibonacci code is executed. Note that “memo” is defined outside of inner() so that it can retain its value over multiple function calls.

var fibonacci = (function() {
  var memo = {};
  function inner(n) {
    var value;
    if (n in memo) {
      value = memo[n];
    }
else {
      if (n === 0 || n === 1)
        value = n;
      else
        value = inner(n - 1) + inner(n - 2);
      memo[n] = value;
   }
    return value;
  }
  return inner;
})();

There is of course a tradeoff involved in remembering values. It is faster to find a particular value, but it takes more memory space to store all of them. You should usually define functions to remember values only if the total number of different values that will be produced is comparatively small, or the expense of recomputing them is very great.



Reference :http://addyosmani.com/blog/faster-javascript-memoization/

No comments:

Post a Comment