Page 1 of 1

SPL Class Speed (Database Filtering VS LimitIterator)

Posted: Wed May 03, 2006 4:55 pm
by santosj
I had a theory that Database SQL filtering of results would be faster than using LimitIterator for the same operation. However, my Database Implementation was total crap, but was still faster than LimitIterator for the same task.

SQL: SELECT * FROM table LIMIT 10

LimitIterator:

Code: Select all

$iterator = new DatabaseIterator("SELECT * FROM table");

$limit = new LimitIterator($result, 0, 10);

foreach($limit as $row)
{

}
This is just an example, the mysqli does not implement Iterator, but the sqlite and PDO do. However, 10 rows won't give you anything, but a million rows would. Also, Foreach is slower than while, about two times slower.

However, I believe LimitIterator would be better for native arrays and not database results. SQL should be used instead of PHP for optimization.

Posted: Wed May 03, 2006 5:23 pm
by Christopher
It seems like limiting the query would be better for quering and just using array_slice() would be better for arrays.

Posted: Wed May 03, 2006 5:43 pm
by santosj
arborint wrote:It seems like limiting the query would be better for quering and just using array_slice() would be better for arrays.
Yeah, but have you tried any benchmarks? Most of SPL is coded in C, so LimitIterator could be easier to use and among the same speed as array_slice()

Code: Select all

$start = microtime(true);

$array = array_fill(0, 1000, 'test');
array_slice():

Code: Select all

$limit = array_slice($array, 0, 10);

foreach(new ArrayIterator($limit) as $value) echo $value ."<br />\n";
LimitIterator:

Code: Select all

foreach(new LimitIterator(new ArrayIterator($array), 0, 10) as $value) echo $value ."<br />\n";

Posted: Wed May 03, 2006 8:10 pm
by Christopher
santosj wrote:Yeah, but have you tried any benchmarks?
Put some timing around the code you posted and let us know the results. ;)

Posted: Wed May 03, 2006 11:42 pm
by santosj
Array_slice:

Code: Select all

$elapse = array();
for($i=0; $i < 1000; $i++)
{
	$start = microtime(true);
	
	$array = array_fill(0, 9000, 'test');
	
	$limit = array_slice($array, 0, 1000);
	
	foreach($limit as $value); 
	
	$end = microtime(true);
	
	$elapse[] = $end-$start;
}

echo 'Average Time is '. (array_sum($elapse)/count($elapse)) .' seconds.';

Code: Select all

0.0060847535133362 seconds.
0.005811027765274 seconds.

Code: Select all

//...
foreach(new ArrayIterator($limit) as $value);
//...

Code: Select all

0.0063099730014801
0.0054824845790863
0.0086558318138123
0.0060664193630219
LimitIterator

Code: Select all

<?php
$elapse = array();
for($i=0; $i < 1000; $i++)
{
	$start = microtime(true);
	
	$array = array_fill(0, 9000, 'test');
	
	foreach(new LimitIterator(new ArrayIterator($array), 0, 1000) as $value); 
	
	$end = microtime(true);
	
	$elapse[] = $end-$start;
}

echo 'Average Time is '. (array_sum($elapse)/count($elapse)) .' seconds.';
?>

Code: Select all

0.0066570975780487 seconds
0.0053631002902985
0.0054222803115845
0.0059147379398346
0.0042640235424042

Code: Select all

<?php
$elapse = array();
for($i=0; $i < 1000; $i++)
{
	$start = microtime(true);
	
	$array = array_fill(0, 9000, 'test');
	
	$limit = array_slice($array, 0, 1000);
	
	while($value = current($limit)) next($limit);
	
	$end = microtime(true);
	
	$elapse[] = $end-$start;
}

echo 'Average Time is '. (array_sum($elapse)/count($elapse)) .' seconds.';
?>

Code: Select all

0.0048755917549133 seconds
0.0059066996574402
0.0073514573574066
0.0031825387477875
0.0064527282714844
These are all averages, so it really seems that it doesn't matter which method you use, it will all give the same amount of time.