Многие, кто сталкивался с xPDO, знают метод $modx->getCollection(). Он возвращает массив полученных xPDO-объектов. Но есть еще метод $modx->getIterator(), который выполняет примерно тоже самое, только гораздо выгодней в плане экономии ресурсов и быстродействия. Попробую кратко описать разницу. $modx->getCollection() получает и возвращает массив сразу со всеми полученными объектами. То есть у нас в момент выполнения данного метода расходуются ресурсы под наполнение переменной-массива сразу всеми полученными объектами. А $modx->getIterator() просто создает дескриптов для перечисления, не инициализируя объектов напрямую. Рассмотрим два пример. Пример 1. $q = $modx->newQuery('modResource');
$q->limit(15000);
$docs = $modx->getCollection('modResource', $q);
foreach($docs as $doc){} Время выполнения: 22 сек. Использование памяти: 389 Mb Пример 2. $q = $modx->newQuery('modResource');
$q->limit(15000);
$docs = $modx->getIterator('modResource', $q);
foreach($docs as $doc){} Время выполнения: 19 сек. Использование памяти: 8.9 Mb Как видите, разница во времени не особо большая, но вот в потреблении памяти просто огромная. Почему так получается? В первом случае MODX получает данные всех объектов и набивает их в результирующий массив, а далее уже происходите перечисление его элементов-объектов. А во втором случае объекты инициализируются только на каждом шаге цикла, при этом в единицу времени существует только одна переменная-объект, затираемая на следующем шаге цикла. В итоге память занимает только один объект, а не 15000. Плюс использования $modx->getIterator() еще и в том, что можно обрубить перечисление, к примеру, еще на первом объекте (в данном случае чисто для примера, по какому-либо условию), что сильно сократит время выполнения скрипта, так как в итоге будет инициализирован только один объект, в то время, как в случае с $modx->getCollection() в любом случае будут инициализированы все 15000 объектов. В связи с этим рассмотри еще два примера. Пример 1. $q = $modx->newQuery('modResource');
$q->limit(15000);
$docs = $modx->getCollection('modResource', $q);
foreach($docs as $doc){
break;
} Время выполнения: 23 сек. Использование памяти: 389 Mb То есть почти без изменений. Потому что перечисление массива не занимает много времени, а основное время уходит именно на создание пятнадцати тысяч объектов. Пример 2. $q = $modx->newQuery('modResource');
$q->limit(15000);
$docs = $modx->getIterator('modResource', $q);
foreach($docs as $doc){
break;
} Время выполнения: 0.1343 сек. Использование памяти: 8.25 Mb Вот здесь время выполнения почти мгновенно. Почему? Давайте еще раз распишем логику:
$q->limit(15000);
foreach($modx->getCollection('modResource', $q) as $doc){
break;
} то есть не создавать переменную $docs, а сразу в цикл закинуть результат выполнения метода $modx->getCollection(), то получаем более привлекательные цифры: Время выполнения: 22.5 сек. Использование памяти: 26.25 Mb
то есть при использовании итератора на каждом шаге выполнается по запросу? Или при вызове getIterator сразу кладется в буфер вся выборка, а потом из нее формируются объекты?
Нет, не выполняется по запросу. Это равносильно while($row = $s->fetch(xPDO::FETCH_ASSOC)){}. Смотри код.
Понял
хорошая заметка))))