Мифы про генераторы

Фанат

oncle terrible
Команда форума
Дяденьки, я опять к вам за факт-чекингом.
Накропал тут статейку, самому прям очень нравится, но перед тем как выпускать её в люди хочется вашей критики.
Do generators really reduce the memory usage?
В первую очередь конечно формулировки, не слишком ли я жоско. С одной стороны потроллить конечно полезно, но хочется чтобы комар носа не подточил.
 

WMix

герр M:)ller
Партнер клуба
я такой пример выложу, когла на мой взгляд генератор оправдан

PHP:
// вот генератор
$iterator = $db
    ->sql("select * from entities limit 1000000")
    ->setMapper(
        static function(array $row){
            return new Entity($row['a'], $row['b'],...);
        })
    ->iterator();


// тут вывод в браузер

header('Content-Type: application/json; charset=utf-8');
echo '[';
$firstline = true;
foreach($iterator as $entity){
    if(!$firstline){
        echo ',';
    }
    echo $entity->toJson();
    ob_flush();
    $firstline = false;
}

echo ']';
 

Фанат

oncle terrible
Команда форума
Главное, как я писал выше, не забыть отключить буферизацию запросов.
А то вся экономия превратится в тыкву. Ну или половина экономии.
 

Тугай

Новичок
По мне это ересь все, прятать цикл в какой-то синтаксический сахар, называть это "чистым кодом" и для важности приплетать итераторы, генераторы еще и расход памяти. Не нужная магия. :)

Они нужны сосем для другого. Итераторы чтоб обойти коллекцию отделив алгоритм обхода от сложности структуры коллекции (массив, список, дерево, что-то свое).
А генераторы, генерить частные случаи этих массивов, списков и деревьев в процессе итерации.

Примеры, с числами фибаначи или четными числами, это просто чтоб показать, что такое генератор.
 

WMix

герр M:)ller
Партнер клуба
набор строк видел? в память это не поместится, а так строка да строкой и flush()
 

Фанат

oncle terrible
Команда форума
набор строк видел? в память это не поместится, а так строка да строкой и flush()
об этом я и говорю. если ты не отключил буферизацию запроса, то как раз и не поместится.
потому что БД тебе и привезёт все строки в пхп одной кучкой.
 

Фанат

oncle terrible
Команда форума
отделив алгоритм обхода от сложности структуры коллекции (массив, список, дерево, что-то свое).
ну я вроде то самое и написал?
ещё хочу полимофизм приплести, типа с помощью генераторов моно любой источник данных представить как массив. очень удобно
 

WMix

герр M:)ller
Партнер клуба
потому что БД тебе и привезёт все строки в пхп одной кучкой.
пропустив все лишнее
PHP:
class Db{
    public function iterator(){
        $stm = $this->getStatement();
        while($row = $stm->fetch(PDO::FETCH_ASSOC)){
            yield $this->mapper($row);
        }
    }
}
и как все строки одной кучкой вернутся?
 

WMix

герр M:)ller
Партнер клуба
а, ну да, есть такое

Код:
$docker stats test
... MEM USAGE / LIMIT     MEM %
... 367.8MiB / 3.854GiB   9.32%


# $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
... 7.098MiB / 3.854GiB   0.18%
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
ещё хочу полимофизм приплести, типа с помощью генераторов моно любой источник данных представить как массив. очень удобно
1. любой источник данных представить как массив к полиморфизму не имеет отношения,
2. источник данных через генераторы представляется как ресурс, а в массив ты можешь складывать его вывод
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
хорошо, сформулирую по-другому
в приведенном примере генератор нужен только для того, чтобы итератор работал по замыканию, но замыкание здесь не нужно, потому что мапинг выборки на объект - это часть read model, не надо инъектить модель в сервис доступа к данным,
и получается, что генератор притянут за уши, чтобы обойти ошибку в архитектуре

тут лучше писать без генератора и без замыкания, на одном итераторе, инъектить не модель в сервис, а сервис в модель - и понятно, и кода меньше
 

WMix

герр M:)ller
Партнер клуба
очень часто использую замыкания, получается коротко и элегантно.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
знаю людей, которые так же говорят о трейтах :)
solid здесь нарушается, кода меньше не становится, просто такое себе javascript-style увлечение колбеками, и генераторы не дают какие-то преимущества, просто компенсируют проблему js-колбеков
 

WMix

герр M:)ller
Партнер клуба
трейты гораздо реже, но понимаю, тех кто их употребляет.
 
Сверху