cache decorator vs global

JavaScript performance comparison

Test case created by ju1ius

Preparation code

<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.3/lodash.min.js"></script>
<script>
var SCALE_CACHE = {},
    SPLIT_SCALE_RX = /[#b]*[1-7]/g,
    SPLIT_SCALE_TESTS = [
      '1b2b345b6b7', '123#4567', '12b345b6b7', '12b34567',
      '123#4#567', '1b2b3b4b5b6b7', '12b3#456b7', '1#23#45#67'
    ],
    $join = [].join;

// double the tests arrays to generate cache hits
SPLIT_SCALE_TESTS = SPLIT_SCALE_TESTS.concat(SPLIT_SCALE_TESTS);
SORT_SCALE_TESTS = SPLIT_SCALE_TESTS.map(splitScale);

function cache_decorator(fn, callback, keygen)
{
  var cache = {};
  return function(input) {
    var key = keygen ? keygen.apply(this, arguments) : input,
        fromCache = cache[key],
        result;
    if (fromCache === undefined) {
      result = fn.apply(this, arguments);
      cache[key] = result;
      return result;
    }
    return callback ? callback(fromCache) : fromCache;
  }
}

function splitScale(scale_str)
{
  return scale_str.match(SPLIT_SCALE_RX);
}
function splitScaleCached(input)
{
  var fromCache = SCALE_CACHE[input], result;
  if (fromCache === undefined) {
    result = splitScale(input);
    SCALE_CACHE[input] = result;
    return result;
  }
  return fromCache;
}
var splitScaleDecorated = cache_decorator(splitScale);
var splitScaleMemoized = _.memoize(splitScale);

function sortReverseJoin(a)
{
  return a.sort().reverse().join(',');
}
function sortCached(input)
{
  var cache_key = input.join(','),
      fromCache = SCALE_CACHE[cache_key],
      result;
  if (fromCache === undefined) {
    result = sortReverseJoin(input);
    SCALE_CACHE[cache_key] = result;
    return result;
  }
  return fromCache;
}
var sortDecorated = cache_decorator(sortReverseJoin/*, null, function(a){
  return a.join(',');
}*/
);
var sortMemoized = _.memoize(sortReverseJoin);

</script>

Preparation code output

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
global cache, string input
SPLIT_SCALE_TESTS.forEach(function(scale) {
  var result = splitScaleCached(scale);
});
pending…
decorator cache, string input
SPLIT_SCALE_TESTS.forEach(function(scale) {
  var result = splitScaleDecorated(scale);
});
pending…
global cache, array input
SORT_SCALE_TESTS.forEach(function(scale) {
  var result = sortCached(scale);
});
pending…
decorator cache, array input
SORT_SCALE_TESTS.forEach(function(scale) {
  var result = sortDecorated(scale);
});
pending…
no cache, string input
SPLIT_SCALE_TESTS.forEach(function(scale) {
  var result = splitScale(scale);
});
pending…
no cache, array input
SORT_SCALE_TESTS.forEach(function(scale) {
  var result = sortReverseJoin(scale);
});
pending…
memoize, string input
SPLIT_SCALE_TESTS.forEach(function(scale) {
  var result = splitScaleMemoized(scale);
});
pending…
memoize, array input
SORT_SCALE_TESTS.forEach(function(scale) {
  var result = sortMemoized(scale);
});
pending…

You can edit these tests or add even more tests to this page by appending /edit to the URL.

Compare results of other browsers

0 comments

Add a comment