Monday, October 16, 2006

EDITED : Currying in Javascript - a Stress Test

The recent post on the recently established but relevent blog on Datastructures and Algorithms titled "What Arays are for " caught my attention the moment he brought the issue of sending multiple parameters over to functions ,and having a function call instead . Hmmm , interesting point but ...does that ring a bell ...Oh yes ! Sriram Krishnan on Functional programming and currying in C# way back at his msdn blog . Right ,so a quick info at what the wikipedia had to say about currying brought to the table some insightful information ...

"the technique of transforming a function that takes multiple arguments into a function that takes a single argument (the first of the arguments to the original function) and returns a new function that takes the remainder of the arguments and returns the result." - (source -wikipedia )

But honestly , i was a little reserved for even contemplating a " iterative function call VS simple array loops" challenge...however i did test it out ... thanks to the interest "What Arays are for" instilled into me early this morning...

After some time testing the awesome capabilities of the "apply" and "arguments" arguments in javascript ... by which you could generate an inheritance sort of capability by which you could forward all arguments in a present to another just by using the targetFunction.apply(this,arguments) ! wow !!! that should definitley save some time for me in the future (apart from seeing if i can port currying to actionscript ! )

So heres the code .... ive adopted it in relation to the simple example from the nice blog Mr.sanjay maintains , and ported a Currying solution as well.... the results are impressive ,and i feel well worth the interrogation !

The specification is simple ...just tryign to find an average from the total calcualted .
/* EXHIBIT A */ does this with without currying , /* EXHIBIT B*/ is what i hacked for WITH CURRYING...

/* javascript code
* @author Bhasker V Kode
* @date 16th October 2006
*/
/* EXHIBIT A - WITHOUT CURRYING */
var timer1 ,timer2;var ar= new Array();
var noOfStudents = 1000; // tested for 1000,10000,etc
function callAverage()
{
var agesOfStudents = new Array();
var i;
for(i=0;i <>
agesOfStudents[i] = i;
}
var avgAge=0;
timer1 =new Date().getTime();
avgAge = calcAverageAge(agesOfStudents, noOfStudents);
timer2 =new Date().getTime();
alert(avgAge +'found in '+(timer2- timer1) +'ms');
window.clearTimeout(timer2);
}
function calcAverageAge (ages, noOfPeople)
{
var sumOfAges = 0;
var averageAge = 0;
var i;
for ( i = 0; i < noOfPeople; i++)
{
sumOfAges += parseInt(ages[i]);
averageAge = sumOfAges/noOfPeople;
}
return averageAge ;
}


/* EXHIBIT B - WITHOUT CURRYING */
function calcAverageAgeWITHCURRYING(f,x){
return function(){
x = [x].concat(Array.prototype.slice.apply(arguments));
return f.apply(this,x);
}
}

function fn1(){
ar[ar.length] = timer1+','+timer2
}
function add(a,b){
return a+b;
}
function callAverageWITHCURRYING(){
var agesOfStudents = new Array();
var i;
/* filling array from DB /etc */
for(i=0;i < noOfStudents;i++){
agesOfStudents[i] = i;
}

/* starting excecution to find avg */
var sum=0;
timer2 =new Date().getTime();
var div = (noOfStudents%2==0)?0:1;
for(i=0;i < style="color: rgb(0, 0, 0); font-style: italic;">sum += calcAverageAgeWITHCURRYING(add,agesOfStudents[i])(agesOfStudents[i+1]);
}
timer2 =new Date().getTime();
alert(avgAge +'found in '+(timer2- timer1) +'ms');
}

************STATISCTICS************
for 100 students :
with currying : 0milli seconds
without currying :0milli seconds

for 1,000 students
with currying : 31 ms
without currying : 15ms

for 10,000 students
with currying : 481 ms
without currying : 31ms

for 100,000 students
with currying : 5812 ms ( and buttons hanged !! )
without currying : 875ms


So there you have it ...To check it out for youself ...add two buttons on your page ,and call the two functions as follows .... 8 )
<input type="button" onclick="callAverageWITHCURRYING();" value="callAverage with currying">
<input type="button" onclick="callAverage();" value="callAverage without currying">

Keep Clicking,
Bhasker V Kode

Technorati Tags:, , , , , , , , ,