Clone an object (v13)

Revision 13 of this benchmark created on


Description

Recursive vs Iterative vs JSON.stringify/decode

Setup

function clone_recursive(object) {
      var result = {};
      for (var key in object) {
        var value = object[key];
        if (typeof value === 'object') {
          result[key] = clone_recursive(value);
        } else {
          result[key] = value;
        }
      }
      return result;
    }
    
    function clone_iterative(object) {
      var result = {};
      var stack = [result, object];
      var curr, base;
      while (curr = stack.pop()) {
        var base = stack.pop();
        for (var key in curr) {
          var value = curr[key];
          if (typeof value === 'object') {
            stack.push(base[key] = {});
            stack.push(value)
          } else {
            base[key] = value;
          }
        }
      }
      return result;
    }
    
    function clone_iterative_linkedList(object) {
      var result = {};
      var item = {
        base: result,
        value: object
      };
      var last = item;
      do {
        var current = item.value;
        var base = item.base;
        for (var key in current) {
          var value = current[key];
          if (typeof value === 'object') {
            var resultValue = base[key] = {};
            last.next = {
              base: resultValue,
              value: value
            };
            last = last.next;
          } else {
            base[key] = value;
          }
        }
      } while (item = item.next);
      return result;
    }
    
    function clone_iterative2(object) {
        var result = {};
        var bases = [result];
        var objects = [object];
        for (var i = 0, length = 1; i < length; ++i) {
            var current = objects[i];
            var base = bases[i];
            for (var key in current) {
                var value = current[key];
                if (typeof value === 'object') {
                    bases.push(base[key] = {});
                    objects.push(value);
                    ++length;
                } else {
                    base[key] = value;
                }
            }
        }
        return result;
    }
    
    function clone_JSON(o) {
      return JSON.parse(JSON.stringify(o));
    }
    
    function makeDeepObject() {
      var root = {};
      var current = root;
      for (var i = 33, max = 136; i < max; i++) {
        var key = String.fromCharCode(i);
        var newObject = {};
        for (var j = 0; j < 25; j++) {
          newObject['a' + j] = {
            x: 1
          };
        }
        current[key] = newObject;
        for (; j < 50; j++) {
          newObject['z' + j] = {
            y: 2
          };
        }
        current = newObject;
      }
      return root;
    }
    
    var mock = makeDeepObject();

Test runner

Ready to run.

Testing in
TestOps/sec
Recursive
clone_recursive(mock)
ready
Iterative: Array
clone_iterative(mock)
ready
Iterative: linkedList
clone_iterative_linkedList(mock)
ready
Iterative: 2 arrays
clone_iterative2(mock)
ready
JSON
clone_JSON(mock)
ready

Revisions

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