@KuzmenkoArtem

Получится ли сэкономить память с yield?

Какой вариант менее затратный с точки зрения памяти

function batch($bigArray) {
    $batchSize = 1000;
    for ($i = 0; $i <= count($bigArray); $i += $batchSize) {
        yield array_slice($bigArray, $i, $batchSize);
    }
}

function chunk($bigArray) {
    $chunkSize = 1000;
    return array_chunk($bigArray, $chunkSize);
}

#1
foreach(batch($bigArray) as $item) {
     $memoryUsage = memory_get_usage();
    //do something
}

#2
foreach(chunk($bigArray) as $item) {
    $memoryUsage = memory_get_usage();
    //do something
}


В первом варианте внутри foreach memory_get_usage выдает меньшее число, но как насчет функции array_slice внутри batch() там же каждую итерацию передается целый масив, не будет ли переполнения памяти в array_slice.

Какой вариант более предпочтительней? или может есть лучшее решение (при условии что массив все же нужно разбить на части)

P.S. массив приходит из-вне, то есть раньше разбить его не предоставляется возможным
Спасибо!
  • Вопрос задан
  • 373 просмотра
Решения вопроса 2
sergiks
@sergiks Куратор тега PHP
♬♬
Почему бы не измерить использование памяти во всех вариантах?
БольшойМассив так и так остаётся в памяти и не копируется целиком в array_slice(). Что будет, если передать его в array_slice()по ссылке – уменьшится использование памяти?

Почему бы вообще не работать со ссылкой на массив и не запоминать положение "курсора"?
reset(), next(), current() – вот это вот всё..

Второй вариант - выгрузить массив из памяти в файл, и читать чанки оттуда с нужной позиции. Например, если массив содержит 32-битные целые, то записать весь массив в бинарный файл, по 4 байта на число. См. pack() и unpack(). Оффсет в файле равен индексу числав массиве * 4 байта.
Ответ написан
VladimirAndreev
@VladimirAndreev
php web dev
А не будет ли наименее затратным по памяти вообще перебор исходного массива foreach'ем и формирование чанка в верхнем цикле и его обработка, когда размер чанка будет достигнут?

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

А в варианте из первого абзаца - массив на миллион строк, массив на 0...1000 строк, и ин-т на позицию в глобальном массиве...
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽