source vs new function (v2)

Revision 2 of this benchmark created by Doug Gale on


Description

See if dynamically generated code will run just as fast.

The idea is to see if dynamically generating OOP implementations with textual templates can run fast.

Preparation HTML

<script>
(function(global) {
    global.mat4 = {
        dynamic: {
                matrixMul: compile(generateMatrixMul())
        },
        static: {
            matrixMul: staticMatrixMul
        },
        loop: {
            matrixMul: arbitraryMatrixMul
        },
        loop4: {
            matrixMul: loopMatrixMul4
        },
        identity: function() {
           return [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1];
        }
    };
    
    global.mat4.a = global.mat4.identity();
    global.mat4.b = global.mat4.identity();

    function compile(iife) {
        return (1,eval)(iife);
    }

    function generateMatrixMul() {
        var iter = [0,1,2,3],
            body;
        body = iter.map(function(r) {
            return iter.map(function(c) {
                return iter.map(function(s) {
                    return 'a[' + n(r*4+s) + ']' +
                        '*' +
                        'b[' + n(s*4+c) + ']';
                }).join('+');
            }).join(',\n');
        }).join(',\n');
        
        return ['(function(a,b) { return [', body, ']; })'].join('');
        
        function n(x) {
            return ('  ' + x).substr(-2);
        }
    }
    
    function staticMatrixMul(a,b) {
        return [
            a[ 0]*b[ 0]+a[ 1]*b[ 4]+a[ 2]*b[ 8]+a[ 3]*b[12],
            a[ 0]*b[ 1]+a[ 1]*b[ 5]+a[ 2]*b[ 9]+a[ 3]*b[13],
            a[ 0]*b[ 2]+a[ 1]*b[ 6]+a[ 2]*b[10]+a[ 3]*b[14],
            a[ 0]*b[ 3]+a[ 1]*b[ 7]+a[ 2]*b[11]+a[ 3]*b[15],
            a[ 4]*b[ 0]+a[ 5]*b[ 4]+a[ 6]*b[ 8]+a[ 7]*b[12],
            a[ 4]*b[ 1]+a[ 5]*b[ 5]+a[ 6]*b[ 9]+a[ 7]*b[13],
            a[ 4]*b[ 2]+a[ 5]*b[ 6]+a[ 6]*b[10]+a[ 7]*b[14],
            a[ 4]*b[ 3]+a[ 5]*b[ 7]+a[ 6]*b[11]+a[ 7]*b[15],
            a[ 8]*b[ 0]+a[ 9]*b[ 4]+a[10]*b[ 8]+a[11]*b[12],
            a[ 8]*b[ 1]+a[ 9]*b[ 5]+a[10]*b[ 9]+a[11]*b[13],
            a[ 8]*b[ 2]+a[ 9]*b[ 6]+a[10]*b[10]+a[11]*b[14],
            a[ 8]*b[ 3]+a[ 9]*b[ 7]+a[10]*b[11]+a[11]*b[15],
            a[12]*b[ 0]+a[13]*b[ 4]+a[14]*b[ 8]+a[15]*b[12],
            a[12]*b[ 1]+a[13]*b[ 5]+a[14]*b[ 9]+a[15]*b[13],
            a[12]*b[ 2]+a[13]*b[ 6]+a[14]*b[10]+a[15]*b[14],
            a[12]*b[ 3]+a[13]*b[ 7]+a[14]*b[11]+a[15]*b[15]
        ];
    }
    
    function arbitraryMatrixMul(a, b, dim) {
        var result = [];
        result.length = dim * dim;
        for (var row = 0; row < dim; ++row) {
            for (var col = 0; col < dim; ++col) {
                var t = 0;
                for (var ofs = 0; ofs < dim; ++ofs) {
                    t += a[row*dim+ofs] * b[ofs*dim+col];
                }
                result[row*dim+col] = t;
            }
        }
        return result;
    }
    
    function loopMatrixMul4(a, b) {
        var result = [];
        result.length = 16;
        for (var row = 0; row < 4; ++row) {
            for (var col = 0; col < 4; ++col) {
                var t = 0;
                for (var ofs = 0; ofs < 4; ++ofs) {
                    t += a[row*4+ofs] * b[ofs*4+col];
                }
                result[row*4+col] = t;
            }
        }
        return result;
    }
}(this));

</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Static code
var c = mat4.static.matrixMul(mat4.a, mat4.b);
 
ready
Generated code
var c = mat4.dynamic.matrixMul(mat4.a, mat4.b);
 
ready
Loop
var c = mat4.loop.matrixMul(mat4.a, mat4.b, 4);
 
ready
Loop 4
var c = mat4.loop4.matrixMul(mat4.a, mat4.b);
 
ready

Revisions

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

  • Revision 1: published by Doug Gale on
  • Revision 2: published by Doug Gale on