What are the advantages of using a Generator (yield) in PHP?

8

Since PHP 5.5 was implemented in the Generator language. It can be used inside a function from the keyword yield .

In the Manual , we have an example where one is compared to the function range(0, 1000000) (which theoretically it would spend 100MB of memory) and a xrange implementation through generators (which would reduce memory consumption to 1 kilobyte).

Example of the manual:

<?php
function xrange($start, $limit, $step = 1) {
    if ($start < $limit) {
        if ($step <= 0) {
            throw new LogicException('Step must be +ve');
        }

        for ($i = $start; $i <= $limit; $i += $step) {
            yield $i;
        }
    } else {
        if ($step >= 0) {
            throw new LogicException('Step must be -ve');
        }

        for ($i = $start; $i >= $limit; $i += $step) {
            yield $i;
        }
    }
}

/*
 * Note that both range() and xrange() result in the same
 * output below.
 */

echo 'Single digit odd numbers from range():  ';
foreach (range(1, 9, 2) as $number) {
    echo "$number ";
}
echo "\n";

echo 'Single digit odd numbers from xrange(): ';
foreach (xrange(1, 9, 2) as $number) {
    echo "$number ";
}
?>

In addition to the benefit of saving this memory and simplifying the use of an iterator , what are the other advantages of using generator in PHP?     

asked by anonymous 10.02.2015 / 18:27

1 answer

11

In the background generators are not to save memory. This is another welcome side effect. They exist to create on-demand data streams.

The general idea of it is to be able to better control what happens between the generation of each element of the sequence.

One of the advantages is producing code with better abstractions. You encapsulate the mechanism of how you get the data inside a function and leave another function, probably in a loop , to manipulate this data without worrying about how it was obtained. You separate the mechanism from the business rule.

It also allows what is called lazy evaluation where you only perform the computation of a sequence item when and if you are actually going to use it. Without the generator it is very common to generate huge data sequences, probably in lists or arrays , and spend huge time to generate all the elements and then only actually use some of them and discard the rest. The generator saves memory and processing.

Another use is in creating state machine and Corotinas since it manages to keep state between the calls of its executions. It has natural pauses.

The operation of a generator is more or less the same in all languages that have it. I've already answered something about this in C # which has a very sophisticated generator. There are some good examples.

The gain in memory is relative. If you need all the sequence generated and used at the same time, there is no gain (if you know what you are doing).

Generators are not great for all cases. They provoke in little of overhead . Not that this is a reason not to use, but if it does not provide a real advantage you do not have to accept an overhead .

    
10.02.2015 / 18:37