• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

PHP SPL: Why is RecursiveIteratorIterator 100x slower than recursive search

Marcus

Well-known member
#1
This is the old school recursive search for a node=20 within the grouped nodes:
PHP:
    function search($array, $key, $value)
     {
       $results = array();
    
       search_r($array, $key, $value, $results);
    
       return $results;
     }
    
     function search_r($array, $key, $value, &$results)
     {
       if (!is_array($array))
         return;
    
       if (isset($array[$key]) && $array[$key] == $value)
         $results[] = $array;
    
       foreach ($array as $subarray)
         search_r($subarray, $key, $value, $results);
     }

     $outputArray = search($groupedNodes, 'node_id', 20);
PHP SPL is much cleaner, but also more than 100x slower:
PHP:
     $arrIt = new RecursiveIteratorIterator(new RecursiveArrayIterator($groupedNodes));
    
     foreach ($arrIt as $key =>$sub) {
       $subArray = $arrIt->getSubIterator();
       if (isset($subArray['node_id'])) {
         if ($subArray['node_id'] === 20) {
           $outputArray[] = iterator_to_array($subArray);
         }
       }
     }
Do you have any idea why its so much slower, and if SPL is in general slower than using custom made PHP 4 code?
 

Marcus

Well-known member
#3
When removed $key = , its around the same speed. More than 100 times slower.

I prefer using PHP SPL for this problem, how come it is that much slower?
 

Jeremy

Well-known member
#4
Without looking or running the code its hard to tell. You are however doing 2 separate class instantiations (which, depending on complexity could be difficult) and you convert to an array, which again, depending on the complexity of that function can slow it down.
 

Marcus

Well-known member
#5
To compare it easier, the bare php function takes 1 time point.

These class instantiation takes 70% (0,7 time points) of the time the old school solution needs for its whole seach:
PHP:
$arrIt = new RecursiveIteratorIterator(new RecursiveArrayIterator($groupedNodes));
However this is what slows down everything (99 time points):
PHP:
    foreach ($arrIt as $sub) {
       $subArray = $arrIt->getSubIterator();
       if (isset($subArray['node_id'])) {
         if ($subArray['node_id'] === 20) {
           $outputArray[] = iterator_to_array($subArray);
         }
       }
     }
Do you know if PHP SPL is in general slower than using bare php for solving these array problems?
 

Jeremy

Well-known member
#6
I've never used the functions you are using, so no, I don't know from experience. However, you do an iterator to array conversion (or it seems like it) on every iteration, that may be a slow function (causing the new code to be slower).
 

Marcus

Well-known member
#7
First line takes a bit less time than the whole old school search function. The second line is slowing everything 100x down just browsing through the array. I thought PHPs implementation of build in function would be more efficient.
PHP:
$arrIt = new RecursiveIteratorIterator(new RecursiveArrayIterator($groupedNodes));
foreach ($arrIt as $sub) {}
 

Jeremy

Well-known member
#8
I subscribe by the theory that just because its new, doesn't mean its better. Any reason your older code doesn't work?
 

Marcus

Well-known member
#9
I want to use the more modern functions.

I guess I know now why the newer function is so slow. It walks through the array bit by bit. And that means, that every single item is handled like a sub array (node_id, title, ...) and it tries to walk through it. I want to just check against node_id and then do a ->next(). But that would take me to 'title', and not the next node_id array. There is no such thing as a "get out of this current tree" where after doing that a ->next would bring me to the next node.
 

Marcus

Well-known member
#10
Guess PHP SPL is not doing some wonderful assembler speed accelleration. Maybe it is just a library and casual php functions are executed therein. If that is true, it's better to code my solution in regular PHP.