Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why php generator is slower than an array?

According to comments from documentation: http://php.net/manual/en/language.generators.overview.php
We can see that thanks to generators there is huge memory usage improvement (which is obvious), but there is also 2-3 times slower execution - and that is not so obvious to me.

We gain memory usage improvement at the expense of time - which is not fine.
So, why is php generator slower than an array?

Thanks for tips.

like image 998
szymanskilukasz Avatar asked Jun 28 '14 09:06

szymanskilukasz


1 Answers

When doing optimizations a lot of times you have to choose between speed of execution and memory usage i.e precalculating something and storing it or just doing calculations when you need them.

A generator allows you to write code that uses foreach to iterate over a set of data without needing to build an array in memory, which may cause you to exceed a memory limit, or require a considerable amount of processing time to generate

The manual is referring to a situation when you will not iterate through all results that you generate with your generator. The speed benefit will come from the fact that you don't need to waste processing time and memory by generating items that you don't need.

Generators weren't designed to replace arrays. They were intended as a way to reduce boilerplate code when implementing Iterator objects. Generators will always be slower than arrays, because generator has to generate values each time you call next().

With generators you can do interesting things that you can't do with arrays - for example you can represent infinite sequences (e.g. you could create a range function that only accepts start and step arguments).

I was a little curious so I did a quick comparison between xrange (implemented with generators, as on the PHP manual page) and the built in range function.

Results on my machine (tested with PHP 5.6) were:

range(1, 10000000, 1):

time: 5.2702
memory (byte): 1495269376

xrange(1, 10000000, 1):

time: 1.9010
memory (byte): 262144

Note that the "benchmark" code I was using was iterating through all results and doing simple math operations. The function calls, as displayed above, serve only as a reference for values I was testing with. As always, with very simple benchmarks like this, YMMV.

like image 127
Christian P Avatar answered Sep 20 '22 06:09

Christian P