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.
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.
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.
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.