Re: memory management

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



you hijacked someone else's thread. don't do that.

you are making assuptions about references are correct - the engine is cleverer than
you think (Sara Golemon has a nice blog post about this kind of reference
assuption that you might want to look up)

the word is 'because' not 'cos'.

'short recursive functions' don't equate to performant recursive functions,
deep recursion is going to cost you in performance if the data set is large
and/or the structure to be create ends up being deep.

the recursive function could be replaced with a smart while() loop - which would
eliminate the costly recursion whilst giving you the same nested structure.

Stan Kuhn wrote:
> Hi guys,
> 
> I work with hierarchical world areas organization in my php script.
> 
> It consumes a lot of memory so I'm trying to optimize it.
> 
> The more I try the worse it is ;o)
> 
> Consider following code:
> 
> general::debug("make_hierarchy","before hier split");
> //lets organize areas by parents
> foreach ($in_flat_areas as $area_data)
> {
>   $areas_by_parents[$area_data['parent_id']][]=$area_data;
> }
> unset($in_flat_areas);
> general::debug("make_hierarchy","after hier split");
> 
> 
> OUTPUT:
> 15:25:09 | alloc:14114120 ( 1109632 8.53% rise), peak:15065104 |
> make_hierarchy -- before hier split
> 15:25:09 | alloc:15242104 ( 1127904 7.99% rise), peak:16192000 |
> make_hierarchy -- after hier split
> 
> It has risen by 1.1M that's fine.
> 
> If I change line 
> foreach ($in_flat_areas as $area_data)
> to this
> foreach ($in_flat_areas as &$area_data)
> which I would consider less mamory wasteful cos of using reference instead
> copying and allocating more memory the results are following:
> 
> OUTPUT2:
> 15:28:18 | alloc:14114120 ( 1109632 8.53% rise), peak:15065104 |
> make_hierarchy -- before hier split
> 15:28:18 | alloc:22059472 ( 7945352 56.29% rise), peak:29819936 |
> make_hierarchy -- after hier split
> 
> 8M rise? 
> 
> And check out this
> Commenting out line 
> unset($in_flat_areas);
> is giving following results:
> 
> 15:29:28 | alloc:14114048 ( 1109544 8.53% rise), peak:15065120 |
> make_hierarchy -- before hier split
> 15:29:28 | alloc:29820784 ( 15706656 111.28% rise), peak:29823560 |
> make_hierarchy -- after hier split
> 
> 15M rise?                  
> 
> 
> Then after this I'm calling quite short recursive function that returns
> hierarchical organization of the areas.
> 
> Lets look at that:
> 
> 
>   /**
>    * builds hierarchy of children from given area array organized by parents
>    *
>    * @param $in_parent id of area for which to find children
>    * @param $in_areas_by_parents all areas indexed by parent id
>    * @return false or array of children
>    */
>   function get_children_hierarchy(&$in_parent,&$in_areas_by_parents)
>   {
>     
>     if (!empty($in_areas_by_parents[$in_parent]))
>     { 
>       foreach ($in_areas_by_parents[$in_parent] as $k => &$area_data) 
>       {
>         
>         $children_array[$area_data['id']]=$area_data;
>         
>       	//find children of these ones
>       	if
> (($children=$this->get_children_hierarchy($area_data['id'],$in_areas_by_pare
> nts))!==false)
>       	  $children_array+=$children;
>       	
>       	unset($area_data);
>       }
>       return $children_array;
>     }
>     else 
>       return false;
>   }
> 
> 
> Function is called recursively, input parameters are passed by reference
> presumably not to waste memory.
> 
> //lets loop first level
> $top_parent = 0;
> $in_out_hier_areas=$this->get_children_hierarchy($top_parent,$areas_by_paren
> ts);
> #unset ($areas_by_parents);
> general::debug("make_hierarchy","after all");
> 
> Here are some numbers before and after calling the function
> 
> 15:38:32 | alloc:29531600 ( 15706392 113.61% rise), peak:29534376 |
> make_hierarchy -- after hier split
> 15:38:32 | alloc:38346304 ( 8814560 29.85% rise), peak:39309800 |
> make_hierarchy -- after all
> 
> 9M rise, quite a lot but that's not a point. Look what happens if I change
> function definition to
> function get_children_hierarchy($in_parent,$in_areas_by_parents) 
> 
> just passing input parameters by copying values
> 
> results:
> 
> 15:43:05 | alloc:29532176 ( 15720544 113.82% rise), peak:29534952 |
> make_hierarchy -- after hier split
> 15:43:05 | alloc:38347072 ( 8814752 29.85% rise), peak:39110480 |
> make_hierarchy -- after all
> 
> No difference. 9M rise again. The peak is even few bytes less isn't it.
> 
> 
> 
> After all this there is return of result from function where all this si
> happening...
> 
> If I unset the only variable that have been assigned in this function
> Which is $areas_by_parents, I manage to put down memory usage to 
> 15:51:33 | alloc:30094376 ( 272832 0.91% rise), peak:39399768 |
> make_hierarchy -- after all
> 
> Result of the function has been assigned to in_out variable that has been
> passed by reference to the function $in_out_hier_areas.
> 
> If this is consuming 
> 30094376 - 14114048 aprox 15M that is difference from start to the end of
> the function
> 
> Why after returning from the function I getting this results:
> 15:57:23 | alloc:13559376 ( -16536392 -54.95% rise), peak:39399384 | after
> make hierarchy
> 
> Where is php wasting so much memory? How to control it? How to free up this
> memory when needed? Should I stop using referenced variables? I'm a bit
> confused.
> 
> Thanks
> Stan.
> 

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux