to close or not to close

Benchmark created on


Description

I am trying to decide whether to pass my renderer object rObj (containing the input data and an output object), or to provide the input and output objects in a closure.

I assumed that passing the rObj object as an argument, and then having to look inside it (dereference?) to find the input and output objects would be slower than accessing them directly through a closure.

In Chrome I can sometimes get a minor slowdown when passing the object, but only with a small number of data items, and a reasonably small number of objects. This suggests argument-passing is bad, but dereferencing is reasonably cheap (perhaps cached, even if only once per function call).

The minor cost difference suggests that you can use whichever method looks best for the programmer; the engine is pretty good at dealing with whatever it is told to do. But if you want to go performance-crazy, use the hideous closure method. JS rocks!

Preparation HTML

<script>
  var test = (function() {
    var data = {};
    var output = {};
    var rObj = {
      "data": data,
      "output": output
    };
    for (var i = 32; i < 64; i++) {
      data[String.fromCharCode(i)] = i;
    }
    var objects = [];
    for (var i = 0; i < 120; i++) {
      objects.push({
        renderWith: function(rObj) {
          for (var d in rObj.data) {
            rObj.output[d] = rObj.data[d];
          }
        },
        renderWithout: function() {
          for (var d in data) {
            output[d] = data[d];
          }

        }
      });
    }
    return { "objects": objects,
      "clearOutput": function() {
        output = {};
        rObj.output = {};
      },
      "rObj": rObj
    };
  })();
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
process with passed objects
test.clearOutput();
var rObj = test.rObj;
test.objects.forEach(function(obj) {
  obj.renderWith(rObj);
});
ready
process with objects in closure
test.clearOutput();
test.objects.forEach(function(obj) {
  obj.renderWithout();
});
ready

Revisions

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