CodeBlanks Logo Icon CodeBlanks

Memory efficiency

PHP course · Expert · Lesson 3/54

Learn how generators save memory with large datasets.

Generators save memory

The call range(1, 1000000) builds an array of one million elements; all values are loaded into memory. A generator instead produces one value at a time and holds only one value in memory.

You can see this difference with memory_get_usage(). For large datasets, a generator uses far less memory than an array.

Lazy evaluation

A generator pauses at each yield. The value is produced only when requested by foreach or next(). This lets large datasets flow through without loading into memory.

A file can be read line by line, network data can be processed chunk by chunk. No intermediate arrays are built; one value enters memory at a time, is processed and released.

Exercise Write a squares generator

Write squares(int $n): \Generator: yield the square of each number from 1 to $n. Iterate squares(5) with foreach and print each square.

Show example solution
take int $n, return \Generator. Use a for loop to yield the square of each number from 1 to $n. Then iterate with foreach (squares(5) as $square) and echo $square . "\n";
Example solution:
<?php
function squares(int $n): \Generator {
    for ($i = 1; $i <= $n; $i++) {
        yield $i * $i;
    }
}

foreach (squares(5) as $square) {
    echo $square . "\n";
}

Test yourself

  1. What happens in the call range(1, 1000000)?

    • Nothing, the function returns empty
    • Only the first value is returned
    • An array of one million elements is built in memory
    • A generator is returned, values are produced lazily
    Show answer

    An array of one million elements is built in memory — Correct. range() loads all values into an array; it does not produce them lazily like a generator.

  2. Measure memory usage

    $before = ____(true);
    foreach (squares(5) as $s) { echo $s . "\n"; }
    $after = memory_get_usage(true);
    
    Show answer
    $before = memory_get_usage(true);
    foreach (squares(5) as $s) { echo $s . "\n"; }
    $after = memory_get_usage(true);
    
  3. Match the memory concepts

    range()
    Piles all values into an array
    Generator
    Produces one value at a time
    yield
    Produces a value lazily
    memory_get_usage
    Measures memory usage

All lessons in Expert