4

I mean is there any difference in performance? Which one is able to make the best deep comparison? Sometimes angular's equals function is not able to find every difference.

I have also noticed, that the angular version of this function is not checking the '$$hashKey' key.

sz tech
  • 349
  • 3
  • 11

2 Answers2

3

They basically act the same by comparing the values itself and all inner properties. Performance is also close to being the same, at least this will be a difference in 100-200 ms for 10000 elements. I have created small tests suite, warning: your browser page will freeze for few seconds when you run code snippet. I'm not totally sure is this correct way to measure performance so feel free to suggest better ways.

angular
.module("comparsion", [])
.controller("ComparsionCtrl", function($scope) {
  var testCases = 10000;
  
  console.time("underscore");
  for(var i = 0; i < testCases; i++) {
    var obj = createRandomObj(5, true);
    var obj1 = createRandomObj(5, true);
    _.isEqual(obj, obj1);
  }
  console.timeEnd("underscore");
  
  console.time("angular");
  for(var i = 0; i < testCases; i++) {
    var obj = createRandomObj(5, true);
    var obj1 = createRandomObj(5, true);
    angular.equals(obj, obj1);
  }
  console.timeEnd("angular");
  
  // Random object generator from http://stackoverflow.com/questions/2443901/random-object-generator-in-javascript
  function createRandomObj(fieldCount, allowNested)
{
    var generatedObj = {};

    for(var i = 0; i < fieldCount; i++) {
        var generatedObjField;

        switch(randomInt(allowNested ? 6 : 5)) {

            case 0:
            generatedObjField = randomInt(1000);
            break;

            case 1:
            generatedObjField = Math.random();
            break;

            case 2:
            generatedObjField = Math.random() < 0.5 ? true : false;
            break;

            case 3:
            generatedObjField = randomString(randomInt(4) + 4);
            break;

            case 4:
            generatedObjField = null;
            break;

            case 5:
            generatedObjField = createRandomObj(fieldCount, allowNested);
            break;
        }
        generatedObj[randomString(8)] = generatedObjField;
    }
    return generatedObj;
}

// helper functions

function randomInt(rightBound)
{
    return Math.floor(Math.random() * rightBound);
}

function randomString(size)
{
    var alphaChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var generatedString = '';
    for(var i = 0; i < size; i++) {
        generatedString += alphaChars[randomInt(alphaChars.length)];
    }

    return generatedString;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js"></script>
<div ng-app="comparsion">
  <div ng-controller="ComparsionCtrl"></div>
</div>
G07cha
  • 4,009
  • 2
  • 22
  • 39
  • And what would happen if the $$hashkey appears? – sz tech Aug 31 '16 at 06:38
  • 1
    Oh, I didn't notice your last update. In this case correctly will be to use `angular.equals` because `underscore.isEqual` will fail `$$hashkey` comparison. Or you can use `angular.toJson` function to remove internal elements such as `$$hashkey` – G07cha Aug 31 '16 at 06:41
  • You got downvoted before you've updated your question, it happens probably because people read your question like `_.isEqual vs angular.equals` as you can see from @Ashokreddy's answer but there also was a question about performance. Try to point out most important things first to prevent downvotes. – G07cha Aug 31 '16 at 06:46
  • 1
    @konstantin-azizov, thanks so much for this answer. For those visiting stackoverflow using http**s** your code snippet needs to require underscore from http**s**://underscorejs.org instead of http or loading underscore will be blocked. – Jon Lee-White Sep 03 '16 at 00:45
  • @JonLee-White, thanks for pointing out this issue, unfortunately, official site doesn't serve using a secure protocol, so I've used CloudFlare CDN. – G07cha Sep 03 '16 at 05:41
  • @sztech, sort of, you can test it simply by replacing underscore with lodash CDN link in HTML script tag since they both have the same function – G07cha Sep 01 '17 at 13:26
0

angular.equals:this is angular equals comparision.

_.isEqual:this is underscore equal functionality.you need to import underscore js before using this.

Ashokreddy
  • 352
  • 1
  • 11