Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Optimising a loop for speed

Status
Not open for further replies.

BabyJeffy

Programmer
Joined
Sep 10, 2003
Messages
4,189
Location
GB
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):
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>
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
 
Windows IE 6 has an "Unknown Runtime Error on line 104, char 17".

Windows FireFox 2.0 gives the following results:
Method 1 (7 runs): average=167ms, fastest=156ms, slowest=235ms
Method 2 (7 runs): average=174ms, fastest=156ms, slowest=203ms
[red]Method 3 (7 runs): average=183ms, fastest=172ms, slowest=188ms[/red]
Method 4 (7 runs): average=200ms, fastest=156ms, slowest=438ms


So, as you have found - Method 3 is the worst.

Einstein47
There are no kangaroos in Austria!
[&#91;]Starbase47.com]
 
Hi

Sorry, I added another method, without your permission... It is not supported by the market leader browser, but it s*!ts itself anyway during the test. This method was preferred by the bookmarklet writers, probably for its shortness.
Code:
function parseDivsUsingMethod5()
{
    [b]var[/b] l_oDivs = document.getElementsByTagName([i]'DIV'[/i]);
    [b]var[/b] startTime = [b]new[/b] Date().getTime();
    [b]var[/b] one_div;
    [b]for[/b] ([b]var[/b]r loop=0; one_div=l_oDivs[loop++]; )
    {
        doSomeStuff(one_div);
    }
    [b]var[/b] endTime = [b]new[/b] Date().getTime();
    [b]return[/b] endTime - startTime;
}
FireFox 2.0.0.5
Method 1 (7 runs): average=196ms, fastest=172ms, slowest=297ms
Method 2 (7 runs): average=205ms, fastest=187ms, slowest=219ms
Method 3 (7 runs): average=247ms, fastest=203ms, slowest=453ms
Method 4 (7 runs): average=198ms, fastest=187ms, slowest=219ms
Method 5 (7 runs): average=183ms, fastest=171ms, slowest=188ms
Done

SeaMonkey 1.1.3
Method 1 (7 runs): average=187ms, fastest=156ms, slowest=250ms
Method 2 (7 runs): average=192ms, fastest=172ms, slowest=235ms
Method 3 (7 runs): average=209ms, fastest=188ms, slowest=265ms
Method 4 (7 runs): average=178ms, fastest=156ms, slowest=235ms
Method 5 (7 runs): average=176ms, fastest=156ms, slowest=235ms
Done

Opera 9.22
Method 1 (7 runs): average=256ms, fastest=156ms, slowest=704ms
Method 2 (7 runs): average=167ms, fastest=156ms, slowest=172ms
Method 3 (7 runs): average=3495ms, fastest=3422ms, slowest=3671ms
Method 4 (7 runs): average=167ms, fastest=156ms, slowest=188ms
Method 5 (7 runs): average=158ms, fastest=156ms, slowest=171ms
DoneDone

Safari 3.0.2
Method 1 (7 runs): average=109ms, fastest=109ms, slowest=78ms
Method 2 (7 runs): average=113ms, fastest=109ms, slowest=125ms
Method 3 (7 runs): average=546ms, fastest=546ms, slowest=547ms
Method 4 (7 runs): average=113ms, fastest=109ms, slowest=125ms
Method 5 (7 runs): average=111ms, fastest=109ms, slowest=125ms
Done

Feherke.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top