К содержанию

Медленный getChunk

Добрый день all!
При прогонке набора объектов (~30) через getChunk генерация занимает 0,2 сек. При увеличении объектов, конечно время генерации безобразно растет. Если непосредственно в сниппете формировать html, без getChunk, время 0,07 сек, на том же наборе объектов. Но не хочется мешать php и HTML. В чанк передаются 5 параметров, без фильтров. возможно ли как то сделать генерацию побыстрее, или смирится с этой особенностью modx?
Владимир Бабусенко
Владимир Бабусенко
22 марта 2016, 10:33
modx.pro
3 765
Реклама

Комментарии: 22

Илья Уткин
Илья Уткин Администратор
22 марта 2016, 13:40
    Владимир Бабусенко
    22 марта 2016, 14:32
    подскажите еще как передать свой запрос в 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…
      Илья Уткин
      Илья Уткин Администратор
      22 марта 2016, 14:33
      а если так?
      foreach ($rows as $row) {
        print_r($row);
      }
        Владимир Бабусенко
        22 марта 2016, 14:39
        А так, кидает на главную страницу. В журнале ошибок нет.
    Владимир Бабусенко
    22 марта 2016, 14:53
    В общем, выборку оставил через $modx->getCollection('modResource', $q);
    А генерацию через $pdo = $modx->getService('pdoFetch'); $pdo->getChunk
    Разница по времени не сумашедшая конечно, но есть.
      Сергей Шлоков
      Сергей Шлоков Эксперт
      22 марта 2016, 18:01
      Самый простой вариант оптимизации — это вынести getChunk из цикла. Т.е. вызывать его один раз, а не 30.
        Владимир Бабусенко
        22 марта 2016, 19:54
        Каким образом? Если построение идет однотипного списка с разными данными? В конечном итоге размер списка не постоянен.
          Сергей Шлоков
          Сергей Шлоков Эксперт
          22 марта 2016, 20:06
          На вскидку.
          ...
          // Я бы заменил 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.
            Владимир Бабусенко
            22 марта 2016, 20:18
            Спасибо, попробую. Не знал о таком способе
              Григорий Коленько
              24 марта 2016, 23:45
              Подозреваю, если пдофетч использовать, то такой проблемы нет?
                Сергей Шлоков
                Сергей Шлоков Эксперт
                25 марта 2016, 07:23
                Какой проблемы?
                  Григорий Коленько
                  25 марта 2016, 11:10
                  Со скоростью, как у стандартного вызова. Хотя посмотрел у пдофетч тоже есть парсчанк
                    Василий Наумкин
                    Василий Наумкин Администратор
                    25 марта 2016, 11:15
                    Вот общее описание разницы.

                    Правда, оно уже устарело, сейчас лучше использовать сразу синтаксис Fenom — и богаче и быстрее.
                      Сергей Шлоков
                      Сергей Шлоков Эксперт
                      25 марта 2016, 11:21
                      Да, pdoFetch решает проблему со скоростью. По-моему, Василий писал, что оптимизировал вызов getChunk() в цикле — т.е. он зачитывает его в кеш при первом обращении и потом достает его при повторном запросе. Т.е.
                      foreach ($rows as $row) {
                      	...
                      	// Первый запрос в базу, остальные в кэш
                      	$output .= $pdo->getChunk('name', $row);
                      }
                      Но мой кусок кода будет чуть-чуть быстрее только из-за многочисленных проверок методов класса pdoFetch, сделанных для универсальности и проверки разных условий.

                      П.С. Кстати, ты проверил годовые периоды?

                      П.П.С. И еще хотел сказал про феном, но Василий уже ответил.
                        Григорий Коленько
                        25 марта 2016, 11:24
                        По поводу периодов только вчера внедрил на Лайв обновлённую версию :) спасибо. Я тебе ещё в тп отпишу чуть попозже. Столкнулся с небольшой странностью
                          Сергей Шлоков
                          Сергей Шлоков Эксперт
                          25 марта 2016, 11:58
                          Если ты про ошибку в окне привязки периодов к объектам, то обновись еще раз. )

                          П.С. Прошу прощения у автора за оффтоп.
                          Василий Наумкин
                          Василий Наумкин Администратор
                          25 марта 2016, 12:53
                          Ради интереса проверь свой код на чистом сайте, с отключенным pdoParser, а потом тоже самое через цикл с pdoTools::getChunk().

                          Уверен, разница будет в разы, потому что ты именно что разбираешь все теги через текущий парсер. Если это modParser, то он будет создавать объект на каждый тег и вызывать из него process() — отсюда тормоза.

                          Ну а если включен pdoParser, то он помогает в обработке любого чанка. В pdoTools с версии 2.0 он включен по умолчанию.
                            Сергей Шлоков
                            Сергей Шлоков Эксперт
                            25 марта 2016, 13:46
                            Я использую pdoParser с самого начала, когда он был еще экспериментальным. Но мне казалось, что он передает обработку в modParser. Разве нет? Ты сам писал, что если фастмод выключен, то запускается парсер МОДХ.
                            ...
                            return parent::processElementTags
                              Василий Наумкин
                              Василий Наумкин Администратор
                              25 марта 2016, 14:27
                              fastMode давно уже нет, сейчас в modParser уходит только то, что pdoParser сам не смог разобрать — автоматически.

                              Выбери время, проверь как работает твой код без pdoParser.
                                Сергей Шлоков
                                Сергей Шлоков Эксперт
                                25 марта 2016, 14:37
                                Да, залез в код, вижу разницу
                                case '+':
                                     if (isset($this->modx->placeholders[$innerTag])) {
                                	$output = $this->modx->placeholders[$innerTag];
                                	$processed = true;
                                    }
                                    break;
                                Поэтому сам пользуюсь pdoTools и другим советую.

                                П.С. А почему письма приходят на английском?
                                Василий Наумкин
                                Василий Наумкин Администратор
                                25 марта 2016, 14:41
                                Это значит, что у юзера, который тебе пишет, включен английский интерфейс.

                                Пока что лексикон зависит от отправляющего, а не принимающего, ибо в профиле MODX нет поля для его языка и я не могу прописать его проверку в дополнениях.
                Сергей Шлоков
                Сергей Шлоков Эксперт
                25 марта 2016, 07:33
                У меня опечатка в коде. В первой строчке должно быть так
                $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);
                }
              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
              22