Skip to content

Instantly share code, notes, and snippets.

@richtr
Last active August 29, 2015 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save richtr/10733313 to your computer and use it in GitHub Desktop.
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
/**
*
* 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");
/**
* 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