PHP Generator - processing dataset

In PHP, to work with a dataset, the natural thing to do is to use a loop, store the result to an array and return it. In today's tutorial, we introduce a solution by using a generator.

Return in a loop

For demonstration purposes, imagine we need a function that returns a series of numbers from one to twenty. Typically we will solve it this way:

function oneToTwenty()
{
    $result = [];
    for ($i = 1; $i <= 20; $i++) {
        $result[] = $i;
    }
    return $result;
}

However, storing a large set of data into an array is memory intensive.

We can do a simple benchmark by checking the memory used at run time:

$base = memory_get_usage();
foreach (oneToTwenty() as $i) {
    echo $i . ':';
    echo memory_get_usage() - $base;
    echo "\n";
}

The output is:

1:1368
2:1368
3:1368
4:1368
5:1368
6:1368
7:1368
8:1368
9:1368
10:1368
11:1368
12:1368
13:1368
14:1368
15:1368
16:1368
17:1368
18:1368
19:1368
20:1368

As we can see the memory used while looping the result set is about 1368 byte.

Yield in a loop

We can solve the problem using a generator, and the only difference is that we use yield instead of return:

?

function oneToTwenty()
{
    for ($i = 1; $i <= 20; $i++) {
        yield $i;
    }
}

And let's run the benchmark again, the output is shown s as below:

1:672
2:672
3:672
4:672
5:672
6:672
7:672
8:672
9:672
10:672
11:672
12:672
13:672
14:672
15:672
16:672
17:672
18:672
19:672
20:672

As we can see, we are using far less memory when using a generator.

The end

There is one pitfall when using a generator though, we need to be aware, we are trading the speed with the memory utilization. It is like everything else in programming, there is no right solution but trade-offs.