SPL Class Speed (Database Filtering VS LimitIterator)

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
santosj
Forum Contributor
Posts: 157
Joined: Sat Apr 29, 2006 7:06 pm

SPL Class Speed (Database Filtering VS LimitIterator)

Post 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.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

It seems like limiting the query would be better for quering and just using array_slice() would be better for arrays.
(#10850)
santosj
Forum Contributor
Posts: 157
Joined: Sat Apr 29, 2006 7:06 pm

Post 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";
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post 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. ;)
(#10850)
santosj
Forum Contributor
Posts: 157
Joined: Sat Apr 29, 2006 7:06 pm

Post 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.
Post Reply