Memoization vs Proxies

Benchmark created by Kambfhase on


Description

Lets compare classic memoization to the new harmony proxies.

Preparation HTML

<script>
  // from JavaScript: The Good Parts
  // by D. Crockford
  
  
  function memoizer(memo, fundamental) {
   var shell = function(n) {
    var result = memo[n];
    if (typeof result !== 'number') {
     result = fundamental(shell, n);
     memo[n] = result;
    }
    return result;
   };
   return shell;
  }
  
  function proxyMemo(start, fn) {
   var cache = Object.create(Proxy.create({
    getPropertyDescriptor: function(name) {
     var index = ~~name;
     if (index == name) {
      return {
       get: function() {
        var val = fn.call(this, index);
        Object.defineProperty(this, index, {
         value: val,
         enumerable: true,
         writable: true,
         configurable: true
        });
        return val;
       }
      };
     } else {
      return Object.getOwnPropertyDescriptor(Object.prototype, name);
     }
    },
    getOwnPropertyDescriptor: function(name) {
     return this.getPropertyDescriptor(name);
    },
    getPropertyNames: function() {
     return [];
    },
    getOwnPropertyNames: function() {
     return [];
    },
    delete: function() {
     return false;
    },
    fix: function() {
     return;
    }
   })),
       prop;
   for (prop in start) {
    Object.defineProperty(cache, prop, {
     value: start[prop],
     enumerable: true
    })
   }
   return cache;
  }
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Classic
var fib = memoizer([0, 1], function(shell, n) {
 return shell(n - 1) + shell(n - 2);
}),
    flag = true;
flag &= fib(0) === 0;
flag &= fib(1) === 1;
flag &= fib(3) === 2;
flag &= fib(2) === 1;
flag &= fib(10) === 55;
flag &= fib(8) === 21;
flag &= fib(8) === 21;
flag &= fib(5) === 5;
if (!flag) {
 throw "wrong results!";
}
ready
Proxy
var fib = proxyMemo({
 0: 0,
 1: 1
}, function(n) {
 return this[n - 1] + this[n - 2]
}),
    flag = true;
flag &= fib[0] === 0;
flag &= fib[1] === 1;
flag &= fib[3] === 2;
flag &= fib[2] === 1;
flag &= fib[10] === 55;
flag &= fib[8] === 21;
flag &= fib[8] === 21;
flag &= fib[5] === 5;
if (!flag) {
 throw "wrong results!";
}
ready

Revisions

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

  • Revision 1: published by Kambfhase on