JSON.parse outperforms angular.copy
I've recently been experiencing a pain point in the
speed of my angularJs applications. I did a little browser profiling and noticed
that calls to angular.copy (source code) with large objects were hogging all the time.
While looking through discussion online about the issue (it's apparently pretty well known that angular.copy is slow for large objects), I noticed a peculiar alternative to copying: use JSON.parse(JSON.stringify(obj)).
I went ahead and setup a little test to pit the two solutions against each other, and was a bit surprised by the results. I made a quick angular application that generates objects with a breadth (# of keys) and depth (nested object depth) of N, for N in {1, 10, 100, 200, 300, 400, 500, 600}.
Here's the source code I used to run the test:
Here are the results for a variety of browsers:
Here are the comparative results charted in Excel
While looking through discussion online about the issue (it's apparently pretty well known that angular.copy is slow for large objects), I noticed a peculiar alternative to copying: use JSON.parse(JSON.stringify(obj)).
I went ahead and setup a little test to pit the two solutions against each other, and was a bit surprised by the results. I made a quick angular application that generates objects with a breadth (# of keys) and depth (nested object depth) of N, for N in {1, 10, 100, 200, 300, 400, 500, 600}.
Here's the source code I used to run the test:
<html>
<head>
<script type="text/javascript">
/***************** PASTE A COPY OF angular.min.js HERE ******************/
</script>
<script type="text/javascript">
angular.module("copyTest", [])
.value('nObject', function(n){
var obj = {};
for(var breadth = 0; breadth < n; breadth++){
var innerObj = {"depth": n-breadth};
for (var depth = breadth; depth < n; depth++){
var temp = {};
temp[depth] = innerObj;
innerObj = temp;
}
obj[breadth] = innerObj;
}
this.getObject = function(){
return obj;
}
})
.controller("rootController", function($scope, nObject){
function runTest(n){
var obj = (new nObject(n)).getObject();
//JSON test
var timerName = "JSON n="+n;
console.time(timerName);
var jsonCopy = JSON.parse(JSON.stringify(obj));
console.timeEnd(timerName);
//Angular test
timerName = "Angular n="+n;
console.time(timerName);
var angularCopy = angular.copy(obj);
console.timeEnd(timerName);
}
for (var n = 1; n <= 100; n*=10){
runTest(n);
}
for (var n = 200; n <= 600; n+=100){
runTest(n);
}
$scope.sample = (new nObject(3)).getObject()
});
</script>
</head>
<body ng-app="copyTest">
<div ng-controller="rootController">
console.time was called
<br><br>
Sample object looks like this (n=3): {{sample}}
</div>
</body>
</html>
|
Here are the results for a variety of browsers:
Here are the comparative results charted in Excel
Conclusion: You'll get roughly a 70%-90%
speed boost if you use JSON.parse(JSON.stringify(obj)) instead of
angular.copy(obj) for your deep copies in javascript. Note one caviat:
if your objects contain javascript functions as values, the JSON-parsing
method won't work for you.





ReplyDeleteHello Admin, I have been training students on AngularJS for past 5 years, and at times, I have used your blog as reference for the class training and also for my personal project development. It has been so much useful. Thank you, keep writing more:)
Pls check mine and suggest your ideas -
AngularJS Certification Training in Chennai