Deep Equality Overhead Comparison (v2)

Revision 2 of this benchmark created by Alexander Tsepkov on


Description

JavaScript's inbuilt equality operator is useless for anything but primitive types. In most other languages we take it for granted that simply throwing a == between two operands will perform a deep comparison. RapydScript, being a compiled language, can easily replace == with any operation/sequence it prefers - the problem is avoiding overhead for cases where primitives are being compared. This test explores the actual overhead of deep equality as well as alternatives for reducing it.

Setup

function ՐՏ_Iterable(iterable) {
        if (Array.isArray(iterable) || iterable instanceof String || typeof iterable === "string") {
            return iterable;
        }
        return Object.keys(iterable);
    }
    function eq(a, b) {
        var i;
        if (a === b) {
            return true;
        }
        if (Array.isArray(a) && Array.isArray(b) || a instanceof Object && b instanceof Object) {
            if (a.constructor !== b.constructor || a.length !== b.length) {
                return false;
            }
            if (Array.isArray(a)) {
                for (i = 0; i < len(a); i++) {
                    if (!eq(a[i], b[i])) {
                        return false;
                    }
                }
            } else {
                if (Object.keys(a).length !== Object.keys(b).length) {
                    return false;
                }
                var ՐՏ_Iter3 = ՐՏ_Iterable(a);
                for (var ՐՏ_Index3 = 0; ՐՏ_Index3 < ՐՏ_Iter3.length; ՐՏ_Index3++) {
                    i = ՐՏ_Iter3[ՐՏ_Index3];
                    if (!eq(a[i], b[i])) {
                        return false;
                    }
                }
            }
            return true;
        }
        return false;
    }
    var numA = 1;
    var numB = 1;
    var numC = 2;
    var arrayA = [3, 10, 14, 7];
    var arrayB = [3, 10, 14, 7];
    var arrayC = [9, 11, 20];
    var objectA = {foo: 1, bar: 'baz'};
    var objectB = {foo: 1, bar: 'baz'};
    var objectC = {beer: 99};

Test runner

Ready to run.

Testing in
TestOps/sec
Primitive Positive: Identity
numA === numB
ready
Primitive Positive: Naive Deep Equality
eq(numA, numB)
ready
Primitive Positive: RapydScript Deep Equality
numA === numB || typeof numA === "object" && eq(numA, numB)
ready
Primitive Negative: Identity
numA === numC
ready
Primitive Negative: Naive Deep Equality
eq(numA, numC)
ready
Primitive Negative: RapydScript Deep Equality
numA === numC || typeof numA === "object" && eq(numA, numC)
ready
Object Positive: Naive Deep Equality
eq(objectA, objectB)
ready
Object Positive: RapydScript Deep Equality
objectA === objectB || typeof objectA === "object" && eq(objectA, objectB)
ready
Object Negative: Naive Deep Equality
eq(objectA, objectC)
ready
Object Negative: RapydScript Deep Equality
objectA === objectC || typeof objectA === "object" && eq(objectA, objectC)
ready

Revisions

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

  • Revision 2: published by Alexander Tsepkov on