DEV Community

Raziel Rodrigues
Raziel Rodrigues

Posted on • Edited on

30 tips of code in PHP - Generators

O assunto de hoje é Generator. Neste artigo, vou explicar o que estudei e o link para o repositório com todo o conteúdo.

Generators

Então, vendo que o 'for' não ia ser a melhor solução sempre, os criadores do PHP decidiram implementar os Generators na versão 5.5 da linguagem. Generators são basicamente funções que retornam o resultado de algo iterável sem precisar salvar o resultado da iteração em uma variável. Uma vez que o generator logo após retornar iterar já retorna o resultado, ou seja, não sendo mais necessário fazer o famoso $array[] = $value, economizando então memória e evitando um erro de estouro de pilha de execução.

1 - Uso básico

function yieldCall()
{
    for ($i = 0; $i < 10; $i++) {
        yield $i;
    }
}

$generator = yieldCall();
var_dump($generator);

foreach ($generator as $value) {
    echo $value;
}
Enter fullscreen mode Exit fullscreen mode

Rodando o código, tu consegue perceber que o valor é impresso na tela normalmente, assim como se fosse feito da forma tradicional.

2 - Definindo chave para o iterador

$csv = 'nome;raziel';

function parserYield($input)
{
    foreach (explode(';', $input) as $key => $value) {
        yield uniqid() => $value;
    }
}

foreach (parserYield($csv) as $key => $value) {
    echo ($key);
    echo '<hr>';
    echo $value;
}

echo '<hr>';
Enter fullscreen mode Exit fullscreen mode

3 - Usando com ponteiros

function &genYield()
{
    $value = 3;

    while ($value > 0) {
        yield $value;
    }
}

foreach (genYield() as &$key) {
    echo (--$key);
}

echo '<hr>';
Enter fullscreen mode Exit fullscreen mode

4 - Composição de um array

class Test
{
}

function y()
{
    yield 3;
    yield 4;
}

function x()
{
    yield 1;
    yield from y();
}

$x = x();

foreach ($x as $value) {
    var_dump($value);
}

$x->getReturn();

var_dump(is_array($x->getReturn()));

echo '<hr>';
Enter fullscreen mode Exit fullscreen mode

O Motivo Final

echo '<h1> Exemplo benchmark: </h1> <hr>';

function forEachOnly()
{
    $numeros = [];
    foreach (range(1, 1000000) as $value) {
        $numeros[] = $value;
    }

    echo "Memory peak usage FOREACH: " . memory_get_peak_usage(true) . " bytes \n";
}

function generatorCall()
{
    foreach (range(1, 1000000) as $value) {
        yield $value;
    }
}

function generatorOnly()
{
    foreach (generatorCall() as $value) {
        $value;
    }
    echo "Memory peak usage GENERATOR: " . memory_get_peak_usage(true) . " bytes \n";
}

# forEachOnly(); DESCOMENTA PRA VER ESSE
# generatorOnly(); E DEPOIS DESCOMENTA ESSE
Enter fullscreen mode Exit fullscreen mode

Irei mostrar aqui o benchmark que você mesmo pode testar:

Memory peak usage FOREACH: 44052480 bytes
Memory peak usage GENERATOR: 18878464 bytes
Enter fullscreen mode Exit fullscreen mode

Top comments (0)