Last active
August 29, 2015 13:59
-
-
Save richtr/10733313 to your computer and use it in GitHub Desktop.
Variable-bound Functions: JIT (Just In Time) function binding as an alternative to inline conditional statements within fast render loops
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* Normal method w/ inline conditional statements placed within each render loop | |
* | |
*/ | |
var myVariable = true; | |
function normalLoop() { | |
if ( myVariable === true ) { | |
console.log('Running true code block'); | |
} else { | |
console.log('Running false code block'); | |
} | |
} | |
// *** BENCHMARK *** | |
var startNormal = (new Date()).getTime(); | |
var n = 10000; | |
while ( n-- ) { | |
normalLoop(); | |
} | |
var endNormal = (new Date()).getTime(); | |
console.log("Normal Loop execution time: " + (endNormal - startNormal) + "ms"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Variable -> Function binding mechanism for JavaScript. | |
* | |
* Hypothesis: When we change the value of a JavaScript variable we can bind a conditional | |
* function to run *once per variable assignment* rather than needing to resolve inline conditionals | |
* *once per loop* (e.g. we can abstract away conditional statements from our inline code). | |
* Performing a conditional function assignment once and avoiding conditional statements in a | |
* e.g. requestAnimationFrame loop being called ~60 times per second should result in faster overall | |
* code execution speed. | |
* | |
* By creating a new VariableBoundFunction object we can create a variable that, whenever set, | |
* automatically re-assigns an associated bound function. This mechanism allows us to 'hotwire' a | |
* render loop in to not needing to resolve each inline conditional statement e.g. ~60 times per second. | |
* | |
* Example usage of this interface is provided below. | |
* | |
*/ | |
// *** API *** | |
var VariableBoundFunction = function ( varParent, varName, varDefault, conditionalFunctionBlock ) { | |
var _value, _func; | |
Object.defineProperty( varParent, varName, { | |
get: function () { | |
return _value; | |
}, | |
set: function ( value ) { | |
_value = value; | |
_func = conditionalFunctionBlock.call( varParent, _value ); | |
}, | |
enumerable: true, | |
configurable: true | |
}); | |
// Set provided variable default on start | |
varParent[ varName ] = varDefault; | |
return function () { | |
return _func.call( varParent, _value ); | |
}; | |
}; | |
// *** USAGE *** | |
// Bound variable/function usage | |
var myFunction = new VariableBoundFunction( window, 'myVariable', true, function( newValue ) { | |
if ( newValue === true ) { | |
return function () { | |
console.log('Running true code block'); | |
}; | |
} else { | |
return function () { | |
console.log('Running false code block'); | |
}; | |
} | |
}); | |
// Now we have a fast hotwired render loop! | |
function boundLoop() { | |
myFunction(); // function assignment is set *outside* of the render loop | |
// whenever the value of `myVariable` changes. | |
} | |
// *** BENCHMARK *** | |
var startBound = (new Date()).getTime(); | |
var b = 10000; | |
while ( b-- ) { | |
boundLoop(); | |
} | |
var endBound = (new Date()).getTime(); | |
console.log("Bound loop execution time: " + (endBound - startBound) + "ms"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment