Как стать автором
Поиск
Написать публикацию
Обновить
1
1.2
Александр @phpner

Пользователь

Отправить сообщение

Ещё один человек, ссылающийся на LLM - это сейчас так модно?

Вопрос был не об "Хотите посчитать сумму чисел от 1 до 10M?". Вопрос был в другом. Вы, кстати, так и не смогли на него ответить, а просто ушли в сторону.

Вместо создания массива генератор экономит память, ведь он не держит все элементы сразу.

Покажи, как тут сэкономить память без отказа от массива?

$arr = range(1, 10_000_000); // это сразу съедает сотни МБ и частo упирается в memory_limit

Никак: сам факт range() уже «прожёг» память.

А вот лениво - без промежуточного массива:

function numbers(int $n): Generator {
    for ($i = 1; $i <= $n; $i++) {
        yield $i;
    }
}

$sum = 0;
foreach (numbers(10_000_000) as $x) {
    $sum += $x;
}

Здесь элементы не хранятся в памяти пачкой - выдаются по одному. Пик памяти остаётся малым и не зависит от "размера массива".

Вы ИИ упомянули уже 3-6 раза.

И не просто упомянули, а прям уже утверждаете 😅

Потеряли веру в людей? 🙂

На самом деле я согласился с вами и добавил то, на что вы указали (это до сих пор есть в статье).

Вы общаетесь не с ИИ, а с реальным человеком, который потратил своё время, знания и силы, чтобы написать эту статью. Я с уважением воспринимаю критику и очень рад довести материал до идеала. Но когда комментарий содержит что-то вроде: "На редкость бессмысленная статья. Выглядит так, как будто мне хотят продать кусок дерева", "Вы пошли к своему ИИ за исправлениями и ещё больше запутались. "…

Честно говоря, вы настроены на негатив в каждом комментарии, и общаться просто пропадает желание.

У вас стандартная позиция - “всё бессмысленно”, и объяснили вы всё не так, как я хотел. Окей, зафиксировал.

Просто обратите внимание, статья изначально писалась для среднего уровня.

Спасибо за подробный разбор 🙌

Вы правы: если задача — один раз пройти CSV и сразу обработать строки, то достаточно while (($row = fgetcsv(...))) {...} и никаких генераторов не нужно. В статье я хотел показать другой ракурс: когда важно разделить источник данных и обработку, чтобы не привязывать логику к месту, где читаем/пагинируем, и чтобы потребитель мог остановиться раньше, отфильтровать и т. п.

Про пример с API: да, можно «прямо в цикле» ходить по страницам. Генератор тут полезен тем, что делает пагинацию ленивой и переиспользуемой — потребитель сможет взять ровно столько, сколько нужно, и теми же конструкциями работать с любым источником (файл, БД, API):

function fetchCars(): Generator {
    for ($page = 1; ; $page++) {
        $data = apiRequest('cars', ['page' => $page]);
        if (empty($data['items'])) break;
        foreach ($data['items'] as $car) yield $car;
    }
}

// Пример: взять первые 100 машин дороже 1 млн, лишние страницы не дергаются
foreach (take(filter(fetchCars(), fn($c) => $c['price'] > 1_000_000), 100) as $car) {
    process($car);
}

function filter(Traversable $src, callable $pred): Generator {
    foreach ($src as $x) if ($pred($x)) yield $x;
}
function take(Traversable $src, int $n): Generator {
    $i = 0; foreach ($src as $x) { if ($i++ >= $n) break; yield $x; }
}

Если цель — именно экономия памяти, она и так достигается стримингом. Фишка генераторов — унификация интерфейса: можно вернуть «поток» из функции без аккумуляции массива или без передачи коллбэка, а дальше свободно комбинировать map/filter/take, менять источник динамически и останавливать обработку раньше (меньше I/O).

Информация

В рейтинге
Не участвует
Дата рождения
Зарегистрирован
Активность