array unordered equality

JavaScript performance comparison

Test case created by Jamie Pate

Info

compare two unordered arrays (sets) for equality with and without comparer function

Preparation code

<script src="//cdn.iamwebdeveloper.in/js/es5-shim/1.2.4/es5-shim.min.js"></script>
<script>
Benchmark.prototype.setup = function() {
    var SHORT_COUNT = 40;
   
    function compare(a, b) {
        return String(a).toUpperCase().substr(0,10) == String(b).toUpperCase().substr(0,10);
    }
   
    if (!Array.prototype.uequal1) {
        Array.prototype.uequal1 = function equal(other, compare) {
            function contains(a, b) {
                function bContains(avalue) {
                    function cmp(bvalue) {
                        return compare(avalue, bvalue);
                    }
                    return b.filter(cmp);
                }
                return a.filter(bContains);
            };
            if (this === other) {
                return true;
            }
            if (!other) {
                return false;
            }
            if (!(this instanceof Array) || !(other instanceof Array)) {
                return false;
            }
            if (this.length != other.length) {
                return false;
            }
            var a = this.slice().sort(),
                b = other.slice().sort();
            if ((!compare) || (typeof compare != 'function')) {
                return (JSON.stringify(a) == JSON.stringify(b));
            } else {
                return contains(a, b) && contains(b, a);
            }
        };
    }
   
    if (!Array.prototype.uequal2) {
        Array.prototype.uequal2 = function(other, compare) {
            if (this === other) { return true; }
            if (!other) {
                return false;
            }
            if (!(this instanceof Array) || !(other instanceof Array)) {
                return false;
            }
            if (this.length != other.length) {
                return false;
            }
            var a = this.slice().sort(),
                b = other.slice().sort(),
                i, c = a.length;
            if (compare && typeof compare == 'function') {
                for (i = 0; i < c; ++i) {
                    if (!compare(a[i], b[i])) {
                        return false;
                    }
                }
            } else {
                for (i = 0; i < c; ++i) {
                    if (a[i] != b[i]) {
                        return false;
                    }
                }
            }
            return true;
        }
    }
   
    //http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256BFB0077DFFD
    function areArraysEqual(array1, array2) {
       var temp = new Array();
       if ( (!array1[0]) || (!array2[0]) ) { // If either is not an array
          return false;
       }
       if (array1.length != array2.length) {
          return false;
       }
       // Put all the elements from array1 into a "tagged" array
       for (var i=0; i<array1.length; i++) {
          key = (typeof array1[i]) + "~" + array1[i];
       // Use "typeof" so a number 1 isn't equal to a string "1".
          if (temp[key]) { temp[key]++; } else { temp[key] = 1; }
       // temp[key] = # of occurrences of the value (so an element could appear multiple times)
       }
       // Go through array2 - if same tag missing in "tagged" array, not equal
       for (var i=0; i<array2.length; i++) {
          key = (typeof array2[i]) + "~" + array2[i];
          if (temp[key]) {
             if (temp[key] == 0) { return false; } else { temp[key]--; }
          // Subtract to keep track of # of appearances in array2
          } else { // Key didn't appear in array1, arrays are not equal.
             return false;
          }
       }
       // If we get to this point, then every generated key in array1 showed up the exact same
       // number of times in array2, so the arrays are equal.
       return true;
    }
   
    var arr1 = [ '10Foo', '05Javascript', 'MooTols', 'Zebra', 'Ape', 'ARZaqzäæ', 'ARZaqäæz', 'ARZaqæzä',"Scripta", "tractatos", "nec", "ne.", "Nonumy", "impedit", "denique", "vel", "ut.", "Sed", "alia", "legimus", "senserit", "ex.", "Sed", "at", "minimum", "tacimates", "platonem,", "ne", "quo", "iudicabit", "incorrupte,", "eam", "stet", "facilis", "ei.", "Rebum", "facilisis", "ocurreret", "et", "mea.", "Verear", "periculis", "instructior", "pri", "at,", "vidit", "ullamcorper", "cu", "his.", "Ad", "iusto", "verear", "instructior", "quo.", "Iuvaret", "eripuit", "ea", "quo,", "sed", "agam", "voluptaria", "vituperatoribus", "in.", "Nam", "dicat", "prompta", "te.", "Nec", "at", "melius", "ceteros,", "reque", "admodum", "omittam", "et", "sed.", "An", "eum", "graeci", "mediocritatem,", "regione", "eloquentiam", "ad", "sit.", "Aliquip", "perfecto", "ei", "pri,", "no", "sit", "altera", "regione", "imperdiet.", "Quis", "diceret", "nostrum", "ut", "vim,", "modo", "noluisse", "vim", "cu.", "Ne", "alterum", "appareat", "qualisque", "has,", "cum", "in", "aeque", "admodum.", "Duo", "prima", "dicat", "solet", "at.", "Quidam", "doctus", "intellegam", "et", "est.", "Purto", "soluta", "te", "cum,", "est", "cu", "platonem", "adipiscing.", "Et", "quo", "probo", "tantas", "habemus,", "id", "putant", "dolorum", "vim,", "ad", "iuvaret", "delectus", "forensibus", "pro.", "Eam", "malis", "soluta", "impetus", "ea,", "ne", "ius", "diam", "animal", "regione,", "per", "quas", "viderer", "dignissim", "ne.", "Zü", "binobs", "kudols-li", "vomi", "kod.", "Cunol", "olebumob", "nos", "of.", "Du", "oli", "flapon",  "ex.", "Sed", "at", "minimum", "tacimates", "platonem,", "ne", "quo", "iudicabit", "incorrupte,", "eam", "stet", "facilis", "ei.", "Rebum", "facilisis", "ocurreret", "et", "mea.", "Verear", "periculis", "instructior", "pri", "at,", "vidit", "ullamcorper", "cu", "his.", "Ad", "iusto", "verear", "instructior", "quo.", "Iuvaret", "eripuit", "ea", "quo,", "sed", "agam", "voluptaria", "vituperatoribus", "in.", "Nam", "dicat", "prompta", "te.", "Nec", "at", "melius", "ceteros,", "reque", "admodum", "omittam", "et", "sed.", "An", "eum", "graeci", "mediocritatem,", "regione", "eloquentiam", "ad", "sit.", "Aliquip", "perfecto", "ei", "pri,", "no", "sit", "altera", "regione", "imperdiet.", "Quis", "diceret", "nostrum", "ut", "vim,", "modo", "noluisse", "vim", "cu.", "Ne", "alterum", "appareat", "qualisque", "has,", "cum", "in", "aeque", "admodum.", "Duo", "prima", "dicat", "solet", "at.", "Quidam", "doctus", "intellegam", "et", "est.", "Purto", "soluta", "te", "cum,", "est", "cu", "platonem", "adipiscing.", "Et", "quo", "probo", "tantas", "habemus,", "id", "putant", "dolorum", "vim,", "ad", "iuvaret", "delectus", "forensibus", "pro.", "Eam", "malis", "soluta", "impetus", "ea,", "ne", "ius", "diam", "animal", "regione,", "per", "quas", "viderer", "dignissim", "ne.", "binobs", "kudols-li", "vomi", "kod.", "Cunol", "olebumob", "nos", "of.", "Du", "oli", "flapon", "ga,", "dom", "leitik", "sagolös", "ek.", "Obi", "ibinobsöv", "pimotom", "viän", "fo.", "Te", "ini", "bligi", "gitavan", "plekols,", "ol", "flukis", "tomön", "bem.", "Vat", "kü", "donio."],
    arr2 = [ '10Foo', '05Javascript', 'MooTols', 'Zebra', 'Ape', 'ARZaqzäæ', 'ARZaqäæz', 'ARZaqæzä',"Scripta", "tractatos", "nec", "ne.", "Nonumy", "impedit", "denique", "vel", "ut.", "Sed", "alia", "legimus", "senserit", "ex.", "Sed", "at", "minimum", "tacimates", "platonem,", "ne", "quo", "iudicabit", "incorrupte,", "eam", "stet", "facilis", "ei.", "Rebum", "facilisis", "ocurreret", "et", "mea.", "Verear", "periculis", "instructior", "pri", "at,", "vidit", "ullamcorper", "cu", "his.", "Ad", "iusto", "verear", "instructior", "quo.", "Iuvaret", "eripuit", "ea", "quo,", "sed", "agam", "voluptaria", "vituperatoribus", "in.", "Nam", "dicat", "prompta", "te.", "Nec", "at", "melius", "ceteros,", "reque", "admodum", "omittam", "et", "sed.", "An", "eum", "graeci", "mediocritatem,", "regione", "eloquentiam", "ad", "sit.", "Aliquip", "perfecto", "ei", "pri,", "no", "sit", "altera", "regione", "imperdiet.", "Quis", "diceret", "nostrum", "ut", "vim,", "modo", "noluisse", "vim", "cu.", "Ne", "alterum", "appareat", "qualisque", "has,", "cum", "in", "aeque", "admodum.", "Duo", "prima", "dicat", "solet", "at.", "Quidam", "doctus", "intellegam", "et", "est.", "Purto", "soluta", "te", "cum,", "est", "cu", "platonem", "adipiscing.", "Et", "quo", "probo", "tantas", "habemus,", "id", "putant", "dolorum", "vim,", "ad", "iuvaret", "delectus", "forensibus", "pro.", "Eam", "malis", "soluta", "impetus", "ea,", "ne", "ius", "diam", "animal", "regione,", "per", "quas", "viderer", "dignissim", "ne.", "Zü", "binobs", "kudols-li", "vomi", "kod.", "Cunol", "olebumob", "nos", "of.", "Du", "oli", "flapon",  "ex.", "Sed", "at", "minimum", "tacimates", "platonem,", "ne", "quo", "iudicabit", "incorrupte,", "eam", "stet", "facilis", "ei.", "Rebum", "facilisis", "ocurreret", "et", "mea.", "Verear", "periculis", "instructior", "pri", "at,", "vidit", "ullamcorper", "cu", "his.", "Ad", "iusto", "verear", "instructior", "quo.", "Iuvaret", "eripuit", "ea", "quo,", "sed", "agam", "voluptaria", "vituperatoribus", "in.", "Nam", "dicat", "prompta", "te.", "Nec", "at", "melius", "ceteros,", "reque", "admodum", "omittam", "et", "sed.", "An", "eum", "graeci", "mediocritatem,", "regione", "eloquentiam", "ad", "sit.", "Aliquip", "perfecto", "ei", "pri,", "no", "sit", "altera", "regione", "imperdiet.", "Quis", "diceret", "nostrum", "ut", "vim,", "modo", "noluisse", "vim", "cu.", "Ne", "alterum", "appareat", "qualisque", "has,", "cum", "in", "aeque", "admodum.", "Duo", "prima", "dicat", "solet", "at.", "Quidam", "doctus", "intellegam", "et", "est.", "Purto", "soluta", "te", "cum,", "est", "cu", "platonem", "adipiscing.", "Et", "quo", "probo", "tantas", "habemus,", "id", "putant", "dolorum", "vim,", "ad", "iuvaret", "xyz", "forensibus", "pro.", "Eam", "malis", "soluta", "impetus", "ea,", "ne", "ius", "diam", "animal", "regione,", "per", "quas", "viderer", "dignissim", "ne.", "binobs", "kudols-li", "vomi", "kod.", "Cunol", "olebumob", "nos", "of.", "Du", "oli", "flapon", "ga,", "dom", "leitik", "sagolös", "ek.", "Obi", "ibinobsöv", "pimotom", "viän", "fo.", "Te", "ini", "bligi", "gitavan", "plekols,", "ol", "flukis", "tomön", "bem.", "Vat", "kü", "donio."],
    arr3 = arr1.slice(0,SHORT_COUNT),
    arr4 = arr1.slice(0,SHORT_COUNT);
    arr4[Math.round(SHORT_COUNT/2)] = 'xyz';
};
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
filter
arr1.uequal1(arr2);
pending…
loop
arr1.uequal2(arr2)
pending…
filter short
arr3.uequal1(arr4);
pending…
loop short
arr3.uequal2(arr4);
pending…
filter comparer
arr1.uequal1(arr2, compare);
pending…
loop comparer
arr1.uequal2(arr2, compare)
pending…
short filter comparer
arr3.uequal1(arr4, compare)
pending…
short loop comparer
arr3.uequal2(arr4, compare)
pending…
areArraysEqual
areArraysEqual(arr1, arr2);
pending…
areArraysEqual short
areArraysEqual(arr3, arr4);
pending…

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

Compare results of other browsers

0 comments

Add a comment