Хак: Оптимизация загрузки классов кэша в InstantCMS 2.0.1

+14
2.12K
В InstantCMS 2 в версиях до 2.0.1 включительно загрузка классов кэширования производится независимо от того, разрешено ли кэширование в настройках сайта или нет. Мотивацию разработчиков для этого я точно не знаю. Скорее всего это желание следовать принципам ООП, по которым проверка работы с кэшем должна осуществляться предпочтительно в классе кэширования.

Но поскольку имя параметра настройки 'cache_enabled' вряд ли будет меняться в будущем, то выгоднее в нескольких местах кода вне класса кэширования сделать проверку этого параметра и просто не загружать ничего, связанного с кэшированием, если оно выключено. На моём компе это дало выигрыш порядка 4-5 мс и дополнительную экономию памяти (не сравнивал, забыл).

Изменения делаются в файлах:
\index.php
\system\core\core.php
\system\core\eventsmanager.php
\system\core\model.php

Понимаю, что на данном этапе никто гнаться за этим небольшим ускорением не будет. Выкладываю просто для информации о возможностях оптимизации скорости движка. И как задел на будущее — десяток подобных мелких оптимизаций в сумме дадут 40-50 мс, что уже будет заметно.



\index.php

  1. cmsCache::getInstance()->start();
меняем на
  1. if (cmsConfig::get('cache_enabled')) { cmsCache::getInstance()->start(); }
и строку
  1. cmsCache::getInstance()->stop();
меняем на
  1. if (cmsConfig::get('cache_enabled')) { cmsCache::getInstance()->stop(); }

\system\core\core.php

В функции runWidget()
  1. $cache_key = "widgets.{$widget['id']}";
  2. $cache = cmsCache::getInstance();
  3.  
  4. if (!$widget_object->isCacheable() || false === ($result = $cache->get($cache_key))){
  5. $result = call_user_func_array(array($widget_object, 'run'), array());
  6. if ($result){
  7. // Отдельно кешируем имя шаблона виджета, поскольку оно могло быть
  8. // изменено внутри виджета, а в кеш у нас попадает только тот массив
  9. // который возвращается кодом виджета (без самих свойств $widget_object)
  10. $result['_wd_template'] = $widget_object->getTemplate();
  11. }
  12. $cache->set($cache_key, $result);
  13. }
меняем на
  1. $result = false;
  2. if ($widget_object->isCacheable() && cmsConfig::get('cache_enabled')){
  3. $cache_key = "widgets.{$widget['id']}";
  4. $cache = cmsCache::getInstance();
  5. $result = $cache->get($cache_key);
  6. }
  7.  
  8. if ($result === false){
  9. $result = call_user_func_array(array($widget_object, 'run'), array());
  10. if ($result){
  11. // Отдельно кешируем имя шаблона виджета, поскольку оно могло быть
  12. // изменено внутри виджета, а в кеш у нас попадает только тот массив
  13. // который возвращается кодом виджета (без самих свойств $widget_object)
  14. $result['_wd_template'] = $widget_object->getTemplate();
  15. }
  16. if (isset($cache)) { $cache->set($cache_key, $result); }
  17. }

\system\core\eventsmanager.php

В функции getAllListeners начало и окончание изменить на:

  1. public static function getAllListeners(){
  2.  
  3. $config = cmsConfig::getInstance();
  4. if ($config->cache_enabled) {
  5. $cache = cmsCache::getInstance();
  6. $cache_key = 'events';
  7.  
  8. if (false !== ($structure = $cache->get($cache_key))){
  9. return $structure;
  10. }
  11. }
  12.  
  13. ...
  14.  
  15. if ($config->cache_enabled) {$cache->set($cache_key, $structure, 86400); }
  16.  
  17. return $structure;

\system\core\model.php

В функции getItem() в четырёх местах (строки 935, 959, 1047 и 1089)
  1. if ($this->cache_key){
меняем на
  1. if ($this->cache_key && cmsConfig::get('cache_enabled')){
0
lokanaft lokanaft 9 лет назад #
Вся фишка в том, что её просто нельзя без кэша юзать v
0
WebMan WebMan 9 лет назад #
Почему? Поясните Вашу мысль, пожалуйста.
0
lokanaft lokanaft 9 лет назад #
Например вот этот код:
Код PHP:
  1. /**
  2. * Обновляет кеш списка привязки слушателей к событиям
  3. * @return boolean
  4. */
  5. public static function getAllListeners(){
  6. $cache = cmsCache::getInstance();
  7. $cache_key = 'events';
  8. if (false !== ($structure = $cache->get($cache_key))){
  9. return $structure;
  10. }
Который проверяет наличие кэша и, если его нет, читает кучу папок и файлов и так для каждого вызываемого эвента, которых десятки на одну страницу.
+1
WebMan WebMan 9 лет назад #
Если в настройках кэш отключён, то никакие операции с кэшем не производятся. Это видно в \system\core\cache.php:
Код PHP:
  1. public function get($key){
  2. if (!cmsConfig::get('cache_enabled')) { return false; }
  3. ...
  4. }
  5. public function set($key, $value, $ttl=false){
  6. $config = cmsConfig::getInstance();
  7. if (!$config->cache_enabled) { return false; }
  8. ...
  9. }
И так далее. Во всех функциях класса кэша, везде проверки на разрешение его работы. Поэтому в getAllListeners() класс кэша вызывается, но реально ничего не делает, если в настройках разрешения нет. Если кэш запрещён, то в любом случае перечитываются все манифесты и собирается список евентов. Значит можно смело вынести проверку в getAllListeners() и вообще не вызывать (и даже не загружать) два класса кэша. Что я и сделал в этом хаке.
+2
WebMan WebMan 9 лет назад #
Ещё предложение по поводу кэша исходя из темы про манифесты. Было бы разумно сделать более тонкие настройки кеширования: что именно и насколько кэшировать. Например, сделать галки "Разрешить кэширование ... (событий, виджетов и т.д.)" с полем для указания периода кеширования для каждого пункта. Тогда, например, можно спокойно включить кеширование списка хуков из манифестов на 24 часа и сократить загрузки файлов почти на 30 штук, оставив без кеширования виджеты и другие динамические вещи, которые должны собираться в реальном времени.

Еще от автора

Хуки-хухуки: Исключаем неактивных пользователей из списков
Как иногда начинают свой монолог неопытные стендаперы: «У всех в жизни было такое …
«Расширенная отладка» для InstantCMS 2.14.1 (v.14.1.2) – большое обновление для разработчиков
Новые возможности и удобства, облегчающие разработчикам отладку компонентов и шаблонов.
Использование расширенной отладки. Часть 11. Анализ ошибок 403/404 и редиректов
Одной из неудобных задач при отладке для меня является поиск причины ошибки 403/404.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.