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:

<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

Comments


  1. Hello 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

    ReplyDelete

Post a Comment

Popular Posts