Knockout dependency tracking (v4)

Revision 4 of this benchmark created by Michael Best on


Preparation HTML

<script src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
<script>window.ko30 = window.ko; window.ko = undefined;</script>

<script src="http://bestware.us/knockout/dependency-tracking/knockout-latest-ids-no-try-finally.js"></script>
<script>window.koIdNoTryFinally = window.ko; window.ko = undefined;</script>

<script src="http://bestware.us/knockout/dependency-tracking/knockout-latest-ids-try-finally.js"></script>
<script>window.koIdTryFinally = window.ko; window.ko = undefined;</script>

<script>
function setup(ko) {
    var start = ko.observable(-1),
        observables = [],
        count = 20;

    for (var i = 0; i < count; i++) {
        observables[i] = ko.observable(i+1);
    }

    function arrayReduce(array, value, action) {
        for (var i = 0, j = array.length; i < j; i++)
            value = action(value, array[i], i);
        return value;
    };

    function testComputedDependencies() {
        var c = ko.computed(function() {
            return arrayReduce(observables, start(), function(value1, value2) {
                return value1 + value2();
            });
        }, null, {deferEvaluation:true});
        for (var i=0; i<count; i++) {
            start(i);
            if (c() != i+((count+1)*count/2)) {
                console.log('invalid value', c());
            }
            if (c.getDependenciesCount() != count+1) {
                console.log('wrong dependencies count', c.getDependenciesCount());
            }
        }
        c.dispose();
    }

    function testRollingComputedDependencies() {
        var c = ko.computed(function() {
            for (var value = 0, max = count / 2, i = start(), j = observables.length; max; ++i, --max) {
                if (i === j)
                    i = 0;
                value += observables[i]();
            }
            return value;
        }, null, {deferEvaluation:true});
        for (var i=0; i<count; i++) {
            start(i);
            if (c() <= i) {
                console.log('invalid value', c());
            }
            if (c.getDependenciesCount() != (count/2)+1) {
                console.log('wrong dependencies count', c.getDependenciesCount());
            }
        }
        c.dispose();
    }

    function testRandomComputedDependencies() {
        var c = ko.computed(function() {
            return arrayReduce(observables, start(), function(value1, value2) {
                if (Math.random() >= .5)
                    return value1 + value2();
                else
                    return value1;
            });
        }, null, {deferEvaluation:true});
        for (var i=0; i<count; i++) {
            start(i);
            if (c() < i) {
                console.log('invalid value', c());
            }
            if (c.getDependenciesCount() < 1 || c.getDependenciesCount() > (count+1)) {
                console.log('strange dependencies count', c.getDependenciesCount());
            }
        }
        c.dispose();
    }

    ko.test = {
        testComputedDependencies: testComputedDependencies,
        testRollingComputedDependencies: testRollingComputedDependencies,
        testRandomComputedDependencies: testRandomComputedDependencies
    };
}

setup(window.ko30);
setup(window.koIdNoTryFinally);
setup(window.koIdTryFinally);
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
replace: KO 3.0
window.ko30.test.testComputedDependencies();

 
ready
replace: KO id
window.koIdNoTryFinally.test.testComputedDependencies();
 
ready
replace: KO id with with try/finally
window.koIdTryFinally.test.testComputedDependencies();
 
ready
random: KO 3.0
window.ko30.test.testRandomComputedDependencies();
ready
random: KO id
window.koIdNoTryFinally.test.testRandomComputedDependencies();
ready
random: KO id with try/finally
window.koIdTryFinally.test.testRandomComputedDependencies();
ready
rolling: KO 3.0
window.ko30.test.testRollingComputedDependencies()
ready
rolling: KO id
window.koIdNoTryFinally.test.testRollingComputedDependencies()
ready
rolling: KO id with with try/finally
window.koIdTryFinally.test.testRollingComputedDependencies()
ready

Revisions

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

  • Revision 4: published by Michael Best on