Go Back   CodingForums.com > :: Client side development > JavaScript programming > Post a JavaScript

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 10-15-2012, 02:30 PM   PM User | #1
NadAngel
New to the CF scene

 
Join Date: Oct 2012
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
NadAngel is an unknown quantity at this point
Performance test - comma delimited string

Here is an interesting benchmark test I have made to test the performance of two methods for building a comma delimited string.

An active demo is here:
http://benjaminpajk.host22.com/test1.html

Code:
<!doctype html>
<!--Author: Benjamin Pajk-->
<html lang="sl">
	<head>
		<meta charset="UTF-8">
		<title>HTML5 Template</title>
		<meta name="description" content="">

		<meta http-equiv="X-UA-Compatible" value="IE=9"> 
		
		<!--
		<link rel="stylesheet" href="css/style.css">
		-->
		
		<script src="http://code.jquery.com/jquery-latest.js"></script>
		
		<script type="text/javascript">
		$(document).ready(function(){
				
			var numTests=50; //number of benchmark test samples
			var numIterations=1048576; //one mega (10*1024*1024=1048576) iterations
		
			var testString='';
			var start;
			var end;
			var i;
		
			var testArray=new Array();
		
			function method(){
				this.method1=-1;
				this.method2=-1;
			}
		
			/*perform benchmark test for bulding comma delimited string*/
			//method 1 checks if we need to insert the comma on every iteration
			function method1(){
				testString='';
				start =  new Date();
				insertComma=false;
				for(i=0; i<numIterations; i++){
					if (insertComma){
						testString+=',';
					}else{
						insertComma=true;
					}
					testString+='aa bb';
				}
				end = new Date();
				$('#testResult1').val(end-start);
				return end-start;
			}
			
			//method 2 inserts the comma on every iteration and removes the last comma when it finishes
			function method2(){
				testString='';
				start =  new Date();
				for(i=0; i<numIterations; i++){
					testString+='aa bb,';
				}
				testString=testString.slice(0,testString.length-1);
				end = new Date();
				$('#testResult2').val(end-start);
				return end-start;
			}
			
			//test function (recursive)
			function cmp(x){
				if (x>0){
					//recursive call with 500 ms delay
					setTimeout(function(){cmp(x-1)}, 500);
					var obj=new method();
					obj.method1=method1();
					obj.method2=method2();
					testArray.push(obj);
					$('#parallelTest').text('Testing: '+Math.round((1-x/numTests)*100)+' %');
				}else{
					//calculate the average
					var sumArr1=0;
					var sumArr2=0;
					for(var k=0; k<testArray.length; k++){
						sumArr1+=testArray[k].method1;
						sumArr2+=testArray[k].method2;
					}
					//display average results
					$('#avgResult1').val(sumArr1/testArray.length);
					$('#avgResult2').val(sumArr2/testArray.length);
					$('#testResult1').val('');
					$('#testResult2').val('');
					$('#parallelTest').text('Start parallel test');
				}
			}
			
			$('#parallelTest').click(function(){
				//reset the variables
				testArray=[];
				$('#avgResult1').val('');
				$('#avgResult2').val('');
				//call the benchmark test function
				cmp(numTests);
			});

		});

		</script> 
		
	</head>
	<body>
		<p>
		This script tests the performace of two methods for building comma delimited strings. Each test iterates 1048576 (1024*1024) times and adds "aa bb" with a comma 
		delimeter on every iteration. The test is performed 50 times for both methods and the average time per test is calculated for both methods. The results are expressed 
		in milliseconds.<br>
		</p>
		<p>
		Example: aa bb,aa bb,aa bb,aa bb,aa bb,aa bb<br>
		</p>
		<p>
		<b>method 1:</b> checks if we need to insert the comma on every iteration<br>
		<b>method 2:</b> inserts the comma on every iteration and removes the last comma when it finishes<br>
		</p>
		<p>
		Method 1:<input type="text" id="testResult1" readonly="readonly" value="">ms<br>
		Method 2:<input type="text" id="testResult2" readonly="readonly" value="">ms<br>
		Method 1 (average):<input type="text" id="avgResult1" readonly="readonly" value="">ms<br>
		Method 2 (average):<input type="text" id="avgResult2" readonly="readonly" value="">ms<br>
		<button id="parallelTest">Start parallel test</button>
		</p>
		
		<p>
		Preliminary results show, that IE9 is in favor of the first method while Chrome Firefox and Opera are in favour of the second method.<br>
		Tested browsers:<br>
		Internet Explorer 9.0.7<br>
		Firefox 16.0<br>
		Chrome (ver. 22.0.1229.94 m)<br>
		Opera 12.02<br>
		</p>
		The main difference in browser performace is in the way the function <b>testString=testString.slice(0,testString.length-1);</b> is executed.
		A good interpreter (Firefox, Opera, Chrome) will not actualy copy the string but will just delete the last cell of the existing string.
		<p>
		
		</p>
	</body>
</html>
NadAngel is offline   Reply With Quote
Old 10-15-2012, 04:49 PM   PM User | #2
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,469
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
js performance is more about coding than browsers.

while you may have found a subtle distinction in between browsers for two ways of doing one thing, there are other ways of doing that thing.

for example, this scores about 25X faster than method1 in my quick estimation:
Code:
			function method3(){
				start =  new Date();
				testString=Array(numIterations+1).join('aa bb');
				end = new Date();
				$('#testResult1').val(end-start);
				return end-start;
			}

25:1 pretty much makes the differences between method1 and method2 insignificant.

What's interesting to me is watching how browsers adapt to code over time. The chrome team has jQuery in their dev-cycle nightly perf test batches. What that means is that chrome is developed to run jquery et al faster.

while twiddling knobs in an attempt to get faster real-world code, sometimes browser makers obsolete old best practices.

for example. IE and older firefox is several times faster at populating arrays using array[array.length]=value than array.push(value).

but the chome saw that more code actually uses push().

as a result, here's how chrome scores those two methods:
Code:
MS   TEST
60	array build - [].length trick
32	array build - push()
given how much faster chrome is than ie, i still use [].length, but it's an illustrative example of how everything from duff's devices, early declaration, array length caching and other common performance tweaks don't always result in millisecond payday anymore...
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
rnd me is offline   Reply With Quote
Old 10-16-2012, 10:24 AM   PM User | #3
NadAngel
New to the CF scene

 
Join Date: Oct 2012
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
NadAngel is an unknown quantity at this point
Very informative reply. I was actually trying to test the performance of generating a comma delimited string with two methods. My mistake was that I used constant data "aa bb" to generate the string that may have set you in the wrong direction. Real data would not have been constant, so you have to use a for loop like I did in my two methods. In version 2 my script uses pre-generated random data to build the string. In this case the difference between browsers is not so obvious. My quick tests show, that method2 is more efficient in all tested browsers except Firefox.

An active demo is here:
http://benjaminpajk.host22.com/test2.html

Code:
<!doctype html>
<!--Author: Benjamin Pajk-->
<!-- version 2 -->
<html lang="sl">
	<head>
		<meta charset="UTF-8">
		<title>Benchmark Test</title>
		<meta name="description" content="javaScript benchmark test">

		<meta http-equiv="X-UA-Compatible" value="IE=9"> 
		
		<!--
		<link rel="stylesheet" href="css/style.css">
		-->
		
		<script src="http://code.jquery.com/jquery-latest.js"></script>
		
		<script type="text/javascript">
		$(document).ready(function(){
				
			var numTests=50; //number of benchmark test samples (50)
			var numIterations=1048576; //one mega (10*1024*1024=1048576) iterations
		
			var testString='';
			var testData=new Array();
			var start;
			var end;
			var i;
		
			var testArray=new Array();
		
			function methodObj(){
				this.method1=-1;
				this.method2=-1;
			}
			
			function dataObj(){
				this.data1=-1;
				this.data2=-1;
			}
		
			/*perform benchmark test for bulding comma delimited string*/
			//method 1 checks if we need to insert the comma on every iteration
			function method1(){
				testString='';
				start =  new Date();
				insertComma=false;
				for(i=0; i<numIterations; i++){
					if (insertComma){
						testString+=',';
					}else{
						insertComma=true;
					}
					testString+=testData[i].data1+' '+testData[i].data2;
				}
				end = new Date();
				$('#testResult1').val(end-start);
				return end-start;
			}
			
			//method 2 inserts the comma on every iteration and removes the last comma when it finishes
			function method2(){
				testString='';
				start =  new Date();
				for(i=0; i<numIterations; i++){
					testString+=testData[i].data1+' '+testData[i].data2+',';
				}
				testString=testString.slice(0,testString.length-1);
				end = new Date();
				$('#testResult2').val(end-start);
				return end-start;
			}
			
			//test function (recursive)
			function cmp(x){
				if (x>0){
					//recursive call with 500 ms delay
					setTimeout(function(){cmp(x-1)}, 500);
				
					//create an array of random test data with numIterations elements
					testData=[];
					for(i=0; i<numIterations; i++){
						var newData=new dataObj();
						newData.data1=Math.floor(Math.random()*10);
						newData.data2=Math.floor(Math.random()*10);
						testData.push(newData);
					}
					
					var obj=new methodObj();
					obj.method1=method1();
					obj.method2=method2();
					testArray.push(obj);
					$('#parallelTest').text('Testing: '+Math.round((1-x/numTests)*100)+' %');
				}else{
					//calculate the average
					var sumArr1=0;
					var sumArr2=0;
					for(var k=0; k<testArray.length; k++){
						sumArr1+=testArray[k].method1;
						sumArr2+=testArray[k].method2;
					}
					//display average results
					$('#avgResult1').val(sumArr1/testArray.length);
					$('#avgResult2').val(sumArr2/testArray.length);
					$('#testResult1').val('');
					$('#testResult2').val('');
					$('#parallelTest').text('Start parallel test');
				}
			}
			
			$('#parallelTest').click(function(){
				//reset the variables
				testArray=[];
				$('#avgResult1').val('');
				$('#avgResult2').val('');
				//call the benchmark test function
				cmp(numTests);
			});

		});

		</script> 
		
	</head>
	<body>
		<p>
		This script tests the performace of two methods for building comma delimited strings. Each test iterates 1048576 (1024*1024) times and adds pre-generated random data 
		in format "a b" with a comma delimeter on every iteration. The test is performed 50 times for both methods and the average time per test is calculated for both methods.
		The results are expressed in milliseconds.<br>
		</p>
		<p>
		Data example: "4 5,3 8,9 1,3 5"<br>
		</p>
		<p>
		<b>method 1:</b> checks if we need to insert the comma on every iteration<br>
		<b>method 2:</b> inserts the comma on every iteration and removes the last comma when it finishes<br>
		</p>
		<p>
		Method 1:<input type="text" id="testResult1" readonly="readonly" value="">ms<br>
		Method 2:<input type="text" id="testResult2" readonly="readonly" value="">ms<br>
		Method 1 (average):<input type="text" id="avgResult1" readonly="readonly" value="">ms<br>
		Method 2 (average):<input type="text" id="avgResult2" readonly="readonly" value="">ms<br>
		<button id="parallelTest">Start parallel test</button>
		</p>
		
		<p>
		Preliminary results show, that IE9 is in favor of the first method while Chrome Firefox and Opera are in favour of the second method.<br>
		Tested browsers:<br>
		Internet Explorer 9.0.7<br>
		Firefox 16.0<br>
		Chrome (ver. 22.0.1229.94 m)<br>
		Opera 12.02<br>
		</p>
	</body>
</html>
NadAngel is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 08:58 AM.


Advertisement
Log in to turn off these ads.