Generators
Onde e como
return
Interrompe a execução e retorna
um valor definido;
yield
Pausa a execução e pode retornar
uma sequência de valores.
The heart of a generator function is the yield keyword.
In its simplest form, a yield statement looks much like a return statement,
except that instead of stopping execution of the function and returning,
yield instead provides a value to the code looping over the generator and
pauses execution of the generator function.
https://www.php.net/manual/en/language.generators.syntax.php
O que é
yield "foo";
Lazy Evaluation Memory Efficient
Por que usar?
Executar somente
quando necessário
Somente é usado que é
demandado, o que
economiza recurso de
memória
E o Illuminate (Laravel)?
https://github.com/laravel/framework/pull/29415
https://laravel.com/docs/8.x/collections#lazy-collections
use IlluminateSupportLazyCollection
;
$collection = LazyCollection::times(
1000 * 1000 * 1000)
->filter(fn ($number) => $number %2 == 0)
->take(1000);
Após a versao 6.x o Illuminate adicionou a feature de
LazyCollections que por detrás dos panos usa generators
Fatal error: Allowed memory size of 134217728 bytes
exhausted (tried to allocate 33554440 bytes) in ...
O uso de Generators pode evitar a essa
mensagem de erro, porém lembre que
isso não é uma bala de prata!
Avalie o uso e também como está a
implementação do código, senão o
Generator não vai te salvar
Massa, mas não entendi nada
Então vamos pro código
Generator implements Iterator {
/* Métodos */
public current ( ) : mixed
public key ( ) : mixed
public next ( ) : void
public rewind ( ) : void
public send ( mixed $value ) : mixed
public throw ( Exception $exception ) : mixed
public valid ( ) : bool
public __wakeup ( ) : void
}
function zezeDeCamargoELuciano () {
$lyrics = yield;
print "Pare! Até quando você quer mandar. $lyrics".
PHP_EOL;
$lyrics = yield;
print "Pare! Meus desejos e suas vontades. $lyrics".
PHP_EOL;
$lyrics = yield;
print "Então, PARE! $lyrics". PHP_EOL;
}
$run = zezeDeCamargoELuciano ();
$run->send("E mudar minha vida" );
$run->send("Estão divididas" );
print "..." . PHP_EOL;
print "Solidão está matando a gente
Sufocando a nossa paixão" . PHP_EOL;
$run->send("Liberta o meu coração" );
Exemplo #1
function dividers(int $ofNumber) {
for ($i = 1; $i <= $ofNumber; $i++) {
if ($ofNumber % $i === 0) {
yield $i;
}
}
}
function misc() {
yield 0;
yield from dividers(** **);
yield 777;
}
foreach (misc() as $g) {
print $g . PHP_EOL;
}
Exemplo #2
use IlluminateSupportLazyCollection ;
function dumpMemory($executor)
{
$before = memory_get_peak_usage();
return tap($executor(), function () use ($before) {
$after = memory_get_peak_usage();
var_dump($after - $before);
});
}
dumpMemory(function() {
LazyCollection ::times(1000000)->map(fn($number) => $number*2);
});
Exemplo #3
use IlluminateSupportCollection;
function dumpMemory($executor)
{
$before = memory_get_peak_usage();
return tap($executor(), function () use ($before) {
$after = memory_get_peak_usage();
var_dump($after - $before);
});
}
dumpMemory(function() {
Collection::times(1000000)->map(fn($number) => $number*2);
});
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to
allocate 33554440 bytes) in ...
Exemplo #4
PHP 8 e Fibers
Fiber é um bloco de código que mantém sua própria
pilha (variáveis e estado), que pode ser iniciada, suspensa
ou encerrada cooperativamente pelo código principal e
pela Fiber.
Links
https://www.php.net/manual/en/language.generators.overview.php
https://josephsilber.com/posts/2020/07/29/lazy-collections-in-laravel
https://laravel.com/docs/8.x/collections#lazy-collections
https://dev.to/developertharun/4-ways-to-use-generator-functions-in-javascript-examples-adv
antages-2ohd
https://dev.to/jmau111/make-sense-of-generators-doa
https://adamwathan.me/refactoring-to-collections/

Generators PHP