Медленный getChunk
Добрый день all!
При прогонке набора объектов (~30) через getChunk генерация занимает 0,2 сек. При увеличении объектов, конечно время генерации безобразно растет. Если непосредственно в сниппете формировать html, без getChunk, время 0,07 сек, на том же наборе объектов. Но не хочется мешать php и HTML. В чанк передаются 5 параметров, без фильтров. возможно ли как то сделать генерацию побыстрее, или смирится с этой особенностью modx?
При прогонке набора объектов (~30) через getChunk генерация занимает 0,2 сек. При увеличении объектов, конечно время генерации безобразно растет. Если непосредственно в сниппете формировать html, без getChunk, время 0,07 сек, на том же наборе объектов. Но не хочется мешать php и HTML. В чанк передаются 5 параметров, без фильтров. возможно ли как то сделать генерацию побыстрее, или смирится с этой особенностью modx?
Комментарии: 22
подскажите еще как передать свой запрос в pdo. Делаю так (запрос без xpdo):
sql = «SELECT .....»
$q = new xPDOCriteria($modx, $sql);
$pdo = $modx->getService('pdoFetch');
$rows = $pdo->getCollection('modResource', $q);
foreach ($rows as $row) {
print_r($row->toArray());
}
Но дает 500 ошибку.
при этом если
foreach ($rows as $row) {
echo $row;
}
пишит что ArrayArrayArrayArray…
sql = «SELECT .....»
$q = new xPDOCriteria($modx, $sql);
$pdo = $modx->getService('pdoFetch');
$rows = $pdo->getCollection('modResource', $q);
foreach ($rows as $row) {
print_r($row->toArray());
}
Но дает 500 ошибку.
при этом если
foreach ($rows as $row) {
echo $row;
}
пишит что ArrayArrayArrayArray…
а если так?
foreach ($rows as $row) {
print_r($row);
}
А так, кидает на главную страницу. В журнале ошибок нет.
В общем, выборку оставил через $modx->getCollection('modResource', $q);
А генерацию через $pdo = $modx->getService('pdoFetch'); $pdo->getChunk
Разница по времени не сумашедшая конечно, но есть.
А генерацию через $pdo = $modx->getService('pdoFetch'); $pdo->getChunk
Разница по времени не сумашедшая конечно, но есть.
Самый простой вариант оптимизации — это вынести getChunk из цикла. Т.е. вызывать его один раз, а не 30.
Каким образом? Если построение идет однотипного списка с разными данными? В конечном итоге размер списка не постоянен.
На вскидку.
...
// Я бы заменил getCollection() на newQuery(). Быстрее и меньше памяти жрет.
$rows = $pdo->getCollection('modResource', $q);
$output = '';
// Нужно указать название чанка
$chunk= $modx->getChunk('чанк');
foreach ($rows as $row) {
// В чанке плейсхолдеры должны совпадать с именами ключей массива $row
$modx->setPlaceholders($row);
$modx->getParser()->processElementTags('', $chunk, false, false, '[[', ']]', array(), 10);
$modx->getParser()->processElementTags('', $chunk, true, true, '[[', ']]', array(), 10);
$output .= $chunk;
$modx->unsetPlaceholders($row);
}
На 30 объектах время сократится раза в 2.
Спасибо, попробую. Не знал о таком способе
Подозреваю, если пдофетч использовать, то такой проблемы нет?
Какой проблемы?
Со скоростью, как у стандартного вызова. Хотя посмотрел у пдофетч тоже есть парсчанк
Вот общее описание разницы.
Правда, оно уже устарело, сейчас лучше использовать сразу синтаксис Fenom — и богаче и быстрее.
Правда, оно уже устарело, сейчас лучше использовать сразу синтаксис Fenom — и богаче и быстрее.
Да, pdoFetch решает проблему со скоростью. По-моему, Василий писал, что оптимизировал вызов getChunk() в цикле — т.е. он зачитывает его в кеш при первом обращении и потом достает его при повторном запросе. Т.е.
П.С. Кстати, ты проверил годовые периоды?
П.П.С. И еще хотел сказал про феном, но Василий уже ответил.
foreach ($rows as $row) {
...
// Первый запрос в базу, остальные в кэш
$output .= $pdo->getChunk('name', $row);
}
Но мой кусок кода будет чуть-чуть быстрее только из-за многочисленных проверок методов класса pdoFetch, сделанных для универсальности и проверки разных условий.П.С. Кстати, ты проверил годовые периоды?
П.П.С. И еще хотел сказал про феном, но Василий уже ответил.
По поводу периодов только вчера внедрил на Лайв обновлённую версию :) спасибо. Я тебе ещё в тп отпишу чуть попозже. Столкнулся с небольшой странностью
Если ты про ошибку в окне привязки периодов к объектам, то обновись еще раз. )
П.С. Прошу прощения у автора за оффтоп.
П.С. Прошу прощения у автора за оффтоп.
Ради интереса проверь свой код на чистом сайте, с отключенным pdoParser, а потом тоже самое через цикл с pdoTools::getChunk().
Уверен, разница будет в разы, потому что ты именно что разбираешь все теги через текущий парсер. Если это modParser, то он будет создавать объект на каждый тег и вызывать из него process() — отсюда тормоза.
Ну а если включен pdoParser, то он помогает в обработке любого чанка. В pdoTools с версии 2.0 он включен по умолчанию.
Уверен, разница будет в разы, потому что ты именно что разбираешь все теги через текущий парсер. Если это modParser, то он будет создавать объект на каждый тег и вызывать из него process() — отсюда тормоза.
Ну а если включен pdoParser, то он помогает в обработке любого чанка. В pdoTools с версии 2.0 он включен по умолчанию.
Я использую pdoParser с самого начала, когда он был еще экспериментальным. Но мне казалось, что он передает обработку в modParser. Разве нет? Ты сам писал, что если фастмод выключен, то запускается парсер МОДХ.
...
return parent::processElementTags
fastMode давно уже нет, сейчас в modParser уходит только то, что pdoParser сам не смог разобрать — автоматически.
Выбери время, проверь как работает твой код без pdoParser.
Выбери время, проверь как работает твой код без pdoParser.
Да, залез в код, вижу разницу
П.С. А почему письма приходят на английском?
case '+':
if (isset($this->modx->placeholders[$innerTag])) {
$output = $this->modx->placeholders[$innerTag];
$processed = true;
}
break;
Поэтому сам пользуюсь pdoTools и другим советую.П.С. А почему письма приходят на английском?
Это значит, что у юзера, который тебе пишет, включен английский интерфейс.
Пока что лексикон зависит от отправляющего, а не принимающего, ибо в профиле MODX нет поля для его языка и я не могу прописать его проверку в дополнениях.
Пока что лексикон зависит от отправляющего, а не принимающего, ибо в профиле MODX нет поля для его языка и я не могу прописать его проверку в дополнениях.
У меня опечатка в коде. В первой строчке должно быть так
$rows = $modx->getCollection('modResource', $q); // Про это я говорил заменить на newQuery.
Вот поправленный вариант// Если использовать pdoTools
$where = array(); // Указать необходимое условие
$rows = $pdo->getCollection('modResource', $where); // Второй параметр: или id, или JSON, или массив
$output = '';
// Нужно указать название чанка
$chunk= $modx->getChunk('чанк');
foreach ($rows as $row) {
// В чанке плейсхолдеры должны совпадать с именами ключей массива $row
$modx->setPlaceholders($row);
$modx->getParser()->processElementTags('', $chunk, false, false, '[[', ']]', array(), 10);
$modx->getParser()->processElementTags('', $chunk, true, true, '[[', ']]', array(), 10);
$output .= $chunk;
$modx->unsetPlaceholders($row);
}
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.