Улучшение производительности используя кэширование возвращаемых значений

Многие функции (и методы) в проекте очень часто возвращают одни и те же значения при тех же аргументах, например:

  • математические функции:
    1. function SomeMaths($x)
    2. {
    3. return $x + pow($x, 3.2) - cos($x);
    4. }
  • функции, возвращающие содержимое файла:
    1. function GetConfiguration()
    2. {
    3. return parse_ini_file('configuration.ini');
    4. }
  • функции, возвращающие данные из базы данных:
    1. function GetArticleById($id)
    2. {
    3. $sqlId = mysql_real_escape_string($id);
    4. $result = mysql_query("SELECT `id`, `title` FROM
    5. `article` WHERE `id` = '$sqlId' LIMIT 1");
    6. if (FALSE === $result)
    7. {
    8. throw new Exception('Ошибка в запросе.');
    9. }
    10. return mysql_fetch_assoc($result);
    11. }
    • Если в вашем проекте используются подобные функции, а так же:
      • вы заметил, что эта функция долго выполняется
      • возвращаемые значения всегда одни и те же при тех же передаваемых аргументах
      • функция вызывается более чем один раз

      Задумайтесь о кэширование возвращаемых ею значений.

      Вот как это можно сделать (да, есть и более продвинутые техники, но это не тема этой статьи): добавим статическую переменную в функцию, которая будет хранить ассоциативный массив, связывающий комбинацию аргументов с возвращаемым значением:

      1. function GetArticleById($id)
      2. {
      3. static $cache = array();
      4. // Возвращаемое значение еще не кэшировалось?
      5. if (!isset($cache[$id]))
      6. {
      7. $sqlId = mysql_real_escape_string($id);
      8. $result = mysql_query("SELECT `id`, `title` FROM
      9. `article` WHERE `id` = '$sqlId' LIMIT 1");
      10. if (FALSE === $result)
      11. {
      12. throw new Exception('Ошибка в запросе.');
      13. }
      14. // Добавляем возвращаемое значение в кэш
      15. $cache[$id] = mysql_fetch_assoc($result);
      16. }
      17. // Возвращаем содержимое кэша
      18. return $cache[$id];
      19. }

      Теперь каждый запрос к базе данных, возможно, трудоемкий, будет выполняться только один раз при первом вызове функции. Каждый следующий вызов функции с тем же аргументом будет использовать кэшированное значение.

      Имейте в виду, что количество кэшируемых значений должно быть в разумных пределах (определяемых размером свободной памяти). Если есть миллионы возможных комбинаций аргументов для функции запускаемой один раз, то стоит подумать о других способах оптимизации (и возможно я расскажу о них в следующих публикациях).

      И всегда профилируйте ваш код до того, как использовать такую оптимизацию.

      Блогун - монетизируем блоги

      Rate It! (Average 4.00, 2 votes)

Related Posts

2 Responses to Улучшение производительности используя кэширование возвращаемых значений

  1. gravatar

    В Вашей RSS нельзя получать полные тексты записей, что ли?

  2. gravatar

    нет, нельзя. возможно позже сделаю

Leave a Reply

Mail will not be published