Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between a generator and an array?

Today the PHP team released the PHP 5.5.0 version, which includes support for generators. Reading the documentation, I noticed that it does exactly what it could do with an array.

PHP team generator example:

// Only PHP 5.5 function gen_one_to_three() {     for ($i = 1; $i <= 3; $i++) {         // Note that $i is preserved between yields.         yield $i;     } }  $generator = gen_one_to_three(); foreach ($generator as $value) {     echo "$value\n"; } 

Result:

1 2 3 

But I can do the same thing using arrays. And I can still keep compatible with earlier versions of PHP.

Take a look:

// Compatible with 4.4.9! function gen_one_to_three() {     $results = array();     for ($i = 1; $i <= 3; $i++) {         $results[] = $i;     }      return $results; }  $generator = gen_one_to_three(); foreach ($generator as $value) {     echo "$value\n"; } 

So the question is: what is the purpose of the existence of this new feature? I got to play all examples of documentation without using the new feature, replacing it with array.

Can anyone give a good explanation and perhaps an example that is not necessarily impossible with older versions, but using generators can help in development?

like image 736
David Rodrigues Avatar asked Jun 20 '13 21:06

David Rodrigues


People also ask

What is a generator and how it is used in PHP?

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.

What is a generator in Python?

Python generators are a simple way of creating iterators. All the work we mentioned above are automatically handled by generators in Python. Simply speaking, a generator is a function that returns an object (iterator) which we can iterate over (one value at a time).

How do you create a generator in Python?

It is quite simple to create a generator in Python. It is similar to the normal function defined by the def keyword and uses a yield keyword instead of return. Or we can say that if the body of any function contains a yield statement, it automatically becomes a generator function.

Is range a generator Python?

range is a class of immutable iterable objects. Their iteration behavior can be compared to list s: you can't call next directly on them; you have to get an iterator by using iter . So no, range is not a generator. They are immutable, so they can be used as dictionary keys.


1 Answers

The difference is in terms of efficiency. For example, many languages other than PHP include two range functions, range() and xrange(). This is a really good example of generators and why to use them. Let's build our own:

function range($start, $end) {     $array = array();     for ($i = $start; $i <= $end; $i++) {         $array[] = $i;     }     return $array; } 

Now that's really straight forward. However, for large ranges, it takes a HUGE amount of memory. If we tried to run it with $start = 0 and $end = 100000000, we'd likely run out of memory!

But if we used a generator:

function xrange($start, $end) {     for ($i = $start; $i <= $end; $i++) {         yield $i;     } } 

Now we use constant memory, yet still have an "array" (like structure) that we can iterate over (and use with other iterators) in the same space.

It doesn't replace an array, but it does provide an efficient way of avoiding to need the memory...

But it also provides savings in terms of the generation of items. Since each result is generated as-needed, you could delay execution (fetching or computing) each element until you needed it. So for example, if you needed to fetch an item from a database and do some complex processing around each row, you could delay that with a generator until you actually need that row:

function fetchFromDb($result) {     while ($row = $result->fetchArray()) {         $record = doSomeComplexProcessing($row);         yield $record;     } } 

So if you only needed the first 3 results, you'd only process the first three records.

For more info, I wrote a blog post on this exact subject.

like image 156
ircmaxell Avatar answered Sep 19 '22 05:09

ircmaxell