Бытует мнение, что Битрикс прожорлив, и способен поглотить все ресурсы, которые есть на сервере. Такая проблема действительно существует, и компаниям иногда приходится рассматривать покупку другой конфигурации сервера, например, при сильном расширении ассортимента или увеличении количества задач бизнеса, решаемых обращением к БД.  Посмотрим, как можно сэкономить ресурсы сервера, чтобы таких вопросов не возникало. Сначала приведём пример стандартной задачи и покажем, что оперативная память сервера быстро расходуется при использовании метода GetList. А затем разберёмся, как избежать проблемы. Итак, у нас есть интернет-магазин на 50 000 товаров. У каждого товара есть 20 пользовательских свойств. Задача: пробежаться по всем товарам и что-то сделать, изменить какие-то свойства или выгрузить каталог. В данном примере я показываю код в исследовательских целях.  Итак, что обычно делает программист Битрикс, когда надо получить элементы каталога: На выгрузках в несколько тысяч элементов этот код сработает, и мы получим список элементов. Но уже на 20 000 элементах сервер отправляется в даун. Что же происходит, и почему сервер падает?   Чтобы это выяснить, используем дебаг методы Битрикс и метод PHP memory_get_usage(), который позволяет получить количество используемой оперативной памяти.  Получим такой результат (рис.1). Зафиксируем, что размер выборки одного элемента составляет около 1,5 Мб.   Увеличим выборку до 10 элементов, изменяя переменную $counter, для регулирования количества выводимых элементов: Увеличим выборку до 100 элементов: Ну и увеличим до 1000 элементов: Итак, мы видим что при увеличении количества элементов быстро растёт потребление оперативной памяти, что в конечном счете приводит к тому, что объём данных превышает размер оперативной памяти сервера и сервер падает. Конечно, данную проблему можно решить разбив запрос на несколько, используя параметр nOffset, запустить цикл, получить результат нескольких запросов и решить вопрос.  Но так мы не решаем проблему, а скорее ее усугубляем. Усложняем код и получаем цикл запросов к БД. Можно использовать ключевое слово yield в PHP для создания функции-генератора. Какая польза от yield в PHP?  Возможно, вы уже слышали, но на практике ещё не применяли. Обратимся к справке PHP: Когда вызывается генератор, он возвращает объект, который можно итерировать. Когда вы итерируете этот объект (например, в цикле foreach), PHP вызывает методы итерации объекта каждый раз, когда вам нужно новое значение, после чего сохраняет состояние генератора и при следующем вызове возвращает следующее значение. Когда все значения в генераторе закончились, генератор просто завершит работу, ничего не вернув. После этого основной код продолжит работу, как если бы в массиве закончились элементы для перебора. Вся суть генератора заключается в ключевом слове yield. В самом простом варианте оператор "yield" можно рассматривать как оператор "return", за исключением того, что вместо прекращения работы функции, "yield" только приостанавливает её выполнение и возвращает текущее значение, и при следующем вызове функции она возобновит выполнение с места, на котором прервалась. Как применить yield в нашем случае и что мы получим: При выборке одного элемента результат тот же что и при первом методе: При выборке 10 элементов потребление памяти не меняется: На 100 элементах потребление памяти также не растёт: Ну и проведём финальный эксперимент. Сделаем выборку из 20 000 элементов. Помним, что при первом варианте такая выборка укладывала сервер. В результате скрипт выполнялся минуту, но потребление памяти выросло совсем немного: За счет чего мы получили такой результат? Ответ кроется в природе генераторов. При создании массива весь массив помещается в память целиком, а при использовании генератора при итерировании вы каждый раз получаете только один элемент итерируемого массива. Что и позволяет снизить потребление оперативной памяти. В результате мы получили легкий понятный код. Не переусложнёный пагинацией обращений к БД. И то, что при первом варианте в принципе было невозможно на текущей конфигурации сервера, теперь выполняется, и мы получаем необходимый нам результат. Во-первых, это всё, что связано с выгрузкой каталога интернет-магазина: формирование прайслистов, фидов и другое.  Во-вторых, обработка данных пользователей: чистка от регистраций ботов, изменение формата телефонов, добавление или удаление каких-то свойств. В-третьих, это массовое изменение свойств товаров: цен, характеристик и т.п.  А также другие задачи, для выполнения которых требуется выгрузка большого количества элементов. P.S. Ну и напоследок скажу, что для обработки массивов и объектов PHP предлагает удобные инструменты библиотеки SPL — набор классов для итерации объектов. При их использовании у вас появляются дополнительные возможности при итерировании массивов и объектов.  Технический директор в Bquadro