After some discussion recently about how a loop might be optimised, I thought I'd write a simple test harness and see what kinds of data I got.
Here is the complete test harness that works on 1000 divs. It iterates through each of the 4 methods of looping (that I decided to test) 7 times and reports some data (read below for the data if you don't want to run it yourself):
And the results for MacOSX?
Firefox 2 (MacOSX)
Method 1 (7 runs): average=136ms, fastest=112ms, slowest=222ms
Method 2 (7 runs): average=124ms, fastest=120ms, slowest=147ms
[!]Method 3 (7 runs): average=148ms, fastest=133ms, slowest=231ms[/!]
Method 4 (7 runs): average=125ms, fastest=113ms, slowest=195ms
Safari 3 (MacOSX)
Method 1 (7 runs): average=94ms, fastest=100ms, slowest=99ms
Method 2 (7 runs): average=101ms, fastest=100ms, slowest=104ms
[!]Method 3 (7 runs): average=781ms, fastest=774ms, slowest=786ms[/!]
Method 4 (7 runs): average=82ms, fastest=82ms, slowest=83m
Camino (MacOSX)
Method 1 (7 runs): average=114ms, fastest=102ms, slowest=153ms
Method 2 (7 runs): average=114ms, fastest=109ms, slowest=141ms
[!]Method 3 (7 runs): average=126ms, fastest=121ms, slowest=154ms[/!]
Method 4 (7 runs): average=107ms, fastest=103ms, slowest=134ms
Internet Explorer 5.23 (MacOSX)
Method 1 (7 runs): average=4452ms, fastest=4348ms, slowest=4806ms
Method 2 (7 runs): average=4494ms, fastest=4463ms, slowest=4530ms
[!]Method 3 (7 runs): average=8592ms, fastest=8583ms, slowest=8610ms[/!]
Method 4 (7 runs): average=4452ms, fastest=4438ms, slowest=4470ms
Opera 9.2 (MacOSX)
Method 1 (7 runs): average=148ms, fastest=114ms, slowest=89ms
Method 2 (7 runs): average=107ms, fastest=114ms, slowest=87ms
[!]Method 3 (7 runs): average=3081ms, fastest=3073ms, slowest=3101ms[/!]
Method 4 (7 runs): average=107ms, fastest=113ms, slowest=91ms
Netscape 7.1 (MacOSX)
Method 1 (7 runs): average=3859ms, fastest=3518ms, slowest=4790ms
Method 2 (7 runs): average=3617ms, fastest=3497ms, slowest=3851ms
Method 3 (7 runs): average=3866ms, fastest=3768ms, slowest=4058ms
Method 4 (7 runs): average=3534ms, fastest=3490ms, slowest=3781ms
Looks like we just need to avoid Method 3 and we're sorted!
Anyone care to post up some Windows results?
Cheers,
Jeff
[tt]Jeff's Blog [!]@[/!] CodeRambler
[/tt]
Make sure your web page and css validates properly against the doctype you have chosen - before you attempt to debug a problem!
FAQ216-6094
Here is the complete test harness that works on 1000 divs. It iterates through each of the 4 methods of looping (that I decided to test) 7 times and reports some data (read below for the data if you don't want to run it yourself):
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "[URL unfurl="true"]http://www.w3.org/TR/html4/strict.dtd">[/URL]
<html lang="en">
<head>
<meta http-equiv="content-language" content="en">
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<title>Loop Test</title>
<script type="text/javascript">
function parseDivsUsingMethod1()
{
var l_oDivs = document.getElementsByTagName('DIV');
var startTime = new Date().getTime();
for (var loop=0,max=l_oDivs.length; loop<max; loop++)
{
doSomeStuff(l_oDivs[loop]);
}
var endTime = new Date().getTime();
return endTime - startTime;
}
function parseDivsUsingMethod2()
{
var l_oDivs = document.getElementsByTagName('DIV');
var startTime = new Date().getTime();
for (var loop=0; loop<l_oDivs.length; loop++)
{
doSomeStuff(l_oDivs[loop]);
}
var endTime = new Date().getTime();
return endTime - startTime;
}
function parseDivsUsingMethod3()
{
var l_oDivs = document.getElementsByTagName('DIV');
var startTime = new Date().getTime();
for (var loop=0; loop<document.getElementsByTagName('DIV').length; loop++)
{
doSomeStuff(l_oDivs[loop]);
}
var endTime = new Date().getTime();
return endTime - startTime;
}
function parseDivsUsingMethod4()
{
var l_oDivs = document.getElementsByTagName('DIV');
var startTime = new Date().getTime();
for (var loop=0,max=document.getElementsByTagName('DIV').length; loop<max; loop++)
{
doSomeStuff(l_oDivs[loop]);
}
var endTime = new Date().getTime();
return endTime - startTime;
}
function doSomeStuff(l_oDiv)
{
var l_pHexHash = ['77','88','99','aa','bb','cc','dd','ee','ff'];
var l_sHexString = l_pHexHash[Math.floor(Math.random()*l_pHexHash.length)];
l_sHexString += l_pHexHash[Math.floor(Math.random()*l_pHexHash.length)];
l_sHexString += l_pHexHash[Math.floor(Math.random()*l_pHexHash.length)];
l_oDiv.style.backgroundColor = '#' + l_sHexString;
l_oDiv.style.margin = '3px';
l_oDiv.style.padding = '3px';
}
function performTest(l_nNumberOfTimesLeftToRunTheTestSuite, l_nNumberOfTimesToRunEachTestInTheSuite, l_nMethodNumberToTest)
{
g_oTimerHandle = null;
var l_pResults = new Array();
var l_oMethodFunction = eval('parseDivsUsingMethod' + l_nMethodNumberToTest);
for (var loop=0; loop<l_nNumberOfTimesToRunEachTestInTheSuite; loop++)
{
l_pResults[loop] = l_oMethodFunction();
}
var l_sResult = '';
l_sResult += '<p style="margin:0;padding:0;">Method ' + l_nMethodNumberToTest + ' (' + l_nNumberOfTimesToRunEachTestInTheSuite + ' runs): ';
l_sResult += 'average=' + Math.floor(eval(l_pResults.join('+')) / l_nNumberOfTimesToRunEachTestInTheSuite) + 'ms, ';
l_sResult += 'fastest=' + l_pResults.sort()[0] + 'ms, ';
l_sResult += 'slowest=' + l_pResults[l_pResults.length - 1] + 'ms';
l_sResult += '<\/p>';
if (l_nMethodNumberToTest == 4)
{
g_oTimerHandle = setTimeout('runTestSuite(' + l_nNumberOfTimesLeftToRunTheTestSuite + ',' + l_nNumberOfTimesToRunEachTestInTheSuite + ')', 500);
}
else
{
l_nMethodNumberToTest++;
g_oTimerHandle = setTimeout('performTest(' + l_nNumberOfTimesLeftToRunTheTestSuite + ',' + l_nNumberOfTimesToRunEachTestInTheSuite + ',' + l_nMethodNumberToTest + ')', 100);
}
g_sResult += l_sResult;
}
function runTestSuite(l_nNumberOfTimesLeftToRunTheTestSuite, l_nNumberOfTimesToRunEachTestInTheSuite)
{
g_oTimerHandle = null;
if (l_nNumberOfTimesLeftToRunTheTestSuite > 0)
{
l_nNumberOfTimesLeftToRunTheTestSuite--;
performTest(l_nNumberOfTimesLeftToRunTheTestSuite, l_nNumberOfTimesToRunEachTestInTheSuite, 1);
}
else
{
document.getElementById('results').innerHTML = g_sResult + 'Done';
document.getElementById('results').style.height = 'auto';
}
}
function initialisePage()
{
var l_nNumberOfTimesToRunTheTestSuite = 1;
var l_nNumberOfTimesToRunEachTestInTheSuite = 7;
window['g_sResult'] = '';
var l_oDiv = document.getElementsByTagName('DIV')[0];
var l_sNewDivInnerHTML = '';
var l_sDivInnerHTML = l_oDiv.innerHTML;
for (var loop=0; loop<1000; loop++)
{
l_sNewDivInnerHTML += '<div>' + l_sDivInnerHTML + '</div>';
}
l_oDiv.innerHTML = l_sNewDivInnerHTML;
g_oTimerHandle = setTimeout('runTestSuite(' + l_nNumberOfTimesToRunTheTestSuite + ',' + l_nNumberOfTimesToRunEachTestInTheSuite + ')', 1000);
}
window.onload = initialisePage;
</script>
</head>
<body>
<h3>Loop Test started... this will take a few seconds...</h3>
<p style="height: 5em;border:1px solid black;margin:3px;padding:3px;" id="results"></p>
<div>
Aenean massa. Sed eget tortor. Proin pede. <a href="#">Sed</a> venenatis accumsan diam. Nunc massa erat, mollis <a href="#">sed</a>,
iaculis eu, dignissim vitae, ante. Nulla et tortor. Proin fermentum lacinia elit. <a href="#">Morbi</a> venenatis, tellus quis rutrum
tristique, metus ipsum faucibus neque, vitae tempor risus dui eget diam. Nulla a dolor. Proin turpis odio, ultricies semper, euismod in,
congue at, pede. Suspendisse potenti. <a href="#">Sed</a> ac felis. Cras euismod lorem vitae nibh. Sed ipsum est, accumsan eget, volutpat
eu, blandit in, neque. Sed in nulla. In felis metus, bibendum a, condimentum <a href="#">vel</a>, tincidunt vel, metus.
</div>
</body>
</html>
Firefox 2 (MacOSX)
Method 1 (7 runs): average=136ms, fastest=112ms, slowest=222ms
Method 2 (7 runs): average=124ms, fastest=120ms, slowest=147ms
[!]Method 3 (7 runs): average=148ms, fastest=133ms, slowest=231ms[/!]
Method 4 (7 runs): average=125ms, fastest=113ms, slowest=195ms
Safari 3 (MacOSX)
Method 1 (7 runs): average=94ms, fastest=100ms, slowest=99ms
Method 2 (7 runs): average=101ms, fastest=100ms, slowest=104ms
[!]Method 3 (7 runs): average=781ms, fastest=774ms, slowest=786ms[/!]
Method 4 (7 runs): average=82ms, fastest=82ms, slowest=83m
Camino (MacOSX)
Method 1 (7 runs): average=114ms, fastest=102ms, slowest=153ms
Method 2 (7 runs): average=114ms, fastest=109ms, slowest=141ms
[!]Method 3 (7 runs): average=126ms, fastest=121ms, slowest=154ms[/!]
Method 4 (7 runs): average=107ms, fastest=103ms, slowest=134ms
Internet Explorer 5.23 (MacOSX)
Method 1 (7 runs): average=4452ms, fastest=4348ms, slowest=4806ms
Method 2 (7 runs): average=4494ms, fastest=4463ms, slowest=4530ms
[!]Method 3 (7 runs): average=8592ms, fastest=8583ms, slowest=8610ms[/!]
Method 4 (7 runs): average=4452ms, fastest=4438ms, slowest=4470ms
Opera 9.2 (MacOSX)
Method 1 (7 runs): average=148ms, fastest=114ms, slowest=89ms
Method 2 (7 runs): average=107ms, fastest=114ms, slowest=87ms
[!]Method 3 (7 runs): average=3081ms, fastest=3073ms, slowest=3101ms[/!]
Method 4 (7 runs): average=107ms, fastest=113ms, slowest=91ms
Netscape 7.1 (MacOSX)
Method 1 (7 runs): average=3859ms, fastest=3518ms, slowest=4790ms
Method 2 (7 runs): average=3617ms, fastest=3497ms, slowest=3851ms
Method 3 (7 runs): average=3866ms, fastest=3768ms, slowest=4058ms
Method 4 (7 runs): average=3534ms, fastest=3490ms, slowest=3781ms
Looks like we just need to avoid Method 3 and we're sorted!
Anyone care to post up some Windows results?
Cheers,
Jeff
[tt]Jeff's Blog [!]@[/!] CodeRambler
[/tt]
Make sure your web page and css validates properly against the doctype you have chosen - before you attempt to debug a problem!
FAQ216-6094