Deep Copy vs JSON Stringify / JSON Parse (v10)

Revision 10 of this benchmark created on


Preparation HTML

<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

Setup

function recursiveDeepCopy(o) {
      var newO,
        i;
    
      if (typeof o !== 'object') {
        return o;
      }
      if (!o) {
        return o;
      }
    
      if ('[object Array]' === Object.prototype.toString.apply(o)) {
        newO = [];
        for (i = 0; i < o.length; i += 1) {
          newO[i] = recursiveDeepCopy(o[i]);
        }
        return newO;
      }
    
      newO = {};
      for (i in o) {
        if (o.hasOwnProperty(i)) {
          newO[i] = recursiveDeepCopy(o[i]);
        }
      }
      return newO;
    }
    
    
    function deepCopy(o) {
      var copy = o,
        k;
    
      if (o && typeof o === 'object') {
        copy = Object.prototype.toString.call(o) === '[object Array]' ? [] : {};
        for (k in o) {
          copy[k] = deepCopy(o[k]);
        }
      }
    
      return copy;
    }
    
    function clone(obj) {
      if (obj == null || typeof(obj) != 'object')
        return obj;
    
      var temp = new obj.constructor();
      for (var key in obj)
        temp[key] = clone(obj[key]);
    
      return temp;
    }
    
    var uc = {
      "list": {
        "0oVwOM": {
          "id": "0oVwOM",
          "parent": "pTlmbh",
          "name": "New node",
          "created_at": 1384289621
        },
        "aHxe8k": {
          "id": "aHxe8k",
          "parent": "Fhs2hL",
          "name": "hjkhjkhjk",
          "created_at": 1384354593
        },
        "Fhs2hL": {
          "id": "Fhs2hL",
          "parent": "root",
          "name": "test",
          "created_at": 1383403881
        },
        "HYPSgv": {
          "id": "HYPSgv",
          "parent": "0oVwOM",
          "name": "New node",
          "created_at": 1384342657
        },
        "osFIMf": {
          "id": "osFIMf",
          "parent": "root",
          "name": "New node",
          "created_at": 1384354584
        },
        "PsovXE": {
          "id": "PsovXE",
          "parent": "root",
          "name": "hjkhjkhjk",
          "created_at": 1384354589
        },
        "pTlmbh": {
          "id": "pTlmbh",
          "parent": "Fhs2hL",
          "name": "New node",
          "created_at": 1384289277
        },
        "RbXhdJ": {
          "id": "RbXhdJ",
          "parent": "root",
          "name": "empty",
          "created_at": 1384359806
        }
      },
      "maps": {
        "parent": {
          "pTlmbh": {
            "0oVwOM": {
              "id": "0oVwOM",
              "parent": "pTlmbh",
              "name": "New node",
              "created_at": 1384289621
            }
          },
          "Fhs2hL": {
            "aHxe8k": {
              "id": "aHxe8k",
              "parent": "Fhs2hL",
              "name": "hjkhjkhjk",
              "created_at": 1384354593
            },
            "pTlmbh": {
              "id": "pTlmbh",
              "parent": "Fhs2hL",
              "name": "New node",
              "created_at": 1384289277
            }
          },
          "root": {
            "Fhs2hL": {
              "id": "Fhs2hL",
              "parent": "root",
              "name": "test",
              "created_at": 1383403881
            },
            "osFIMf": {
              "id": "osFIMf",
              "parent": "root",
              "name": "New node",
              "created_at": 1384354584
            },
            "PsovXE": {
              "id": "PsovXE",
              "parent": "root",
              "name": "hjkhjkhjk",
              "created_at": 1384354589
            },
            "RbXhdJ": {
              "id": "RbXhdJ",
              "parent": "root",
              "name": "empty",
              "created_at": 1384359806
            }
          },
          "0oVwOM": {
            "HYPSgv": {
              "id": "HYPSgv",
              "parent": "0oVwOM",
              "name": "New node",
              "created_at": 1384342657
            }
          }
        },
        "path": [
          ["Fhs2hL"],
          ["Fhs2hL", "aHxe8k"],
          ["Fhs2hL", "pTlmbh"],
          ["Fhs2hL", "pTlmbh", "0oVwOM"],
          ["Fhs2hL", "pTlmbh", "0oVwOM", "HYPSgv"],
          ["osFIMf"],
          ["PsovXE"],
          ["RbXhdJ"]
        ]
      }
    };
    
    function recursive(obj) {
      var clone, i;
    
      if (typeof obj !== 'object' || !obj)
        return obj;
    
      if ('[object Array]' === Object.prototype.toString.apply(obj)) {
        clone = [];
        var len = obj.length;
        for (i = 0; i < len; i++)
          clone[i] = recursive(obj[i]);
        return clone;
      }
    
      clone = {};
      for (i in obj)
        if (obj.hasOwnProperty(i))
          clone[i] = recursive(obj[i]);
      return clone;
    }

Test runner

Ready to run.

Testing in
TestOps/sec
Deep Copy
var bes = deepCopy(uc)
ready
JSON Stringify / JSON Parse

try{var bes = JSON.parse(JSON.stringify(uc))}catch(e){}
ready
clone
var bes = clone(uc);
ready
recursive
var bes = recursiveDeepCopy(uc);
ready
$
var bes = jQuery.extend(true, {}, uc);
ready

Revisions

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