"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
2 comments:
Bhasker,
We briefly met during Barcamp chennai. I am with IIT and there are quite a bunch of opportunities for people who want to start companies, as we are looking for people to lead some projects, gain the experience and go chase dreams of their own.
Email me. We need to talk.
- Vijay
vijay at vijayanand.name
Umm..I made an embarrassing mistake in my post. I had actually described something called 'partial application' and not 'currying' - they're similar but not the same :-)
Post a Comment