• Руслан
  • 03 Фев 2009
  • Рубрика: PHP

36 советов. Как писать быстрые PHP скрипты

Странно, что в русскоязычном интернете так мало внимания уделяется оптимизации быстродействия пхп-скриптов… Может быть, те кому важно быстродействие, вообще не пишут на пхп? Шутка :) Пожалуй, буду исправлять ситуацию… и начну с публикации этой небольшой подборки советов. Перечисленные в ней факты следует знать каждому пхп-программисту, который собирается писать скрипты хоть немного сложнее чем форма обратной связи на сайте :)

  1. По возможности объявляйте методы как статические. Они вызываются в 4 раза быстрее.
  2. echo быстрее чем print
  3. Быстрее вызвать echo с несколькими аргументами – строковыми переменными – чем сначала склеивать их в одну.
  4. Устанавливайте максимальное значение для счетчика цикла for вне цикла.
  5. Выполняйте unset для ненужных больше переменных. Особенно это касается больших массивов.
  6. Избегайте “магических” методов (__get, __set и пр.)
  7. В вызовах include и require лучше использовать полный путь к скрипту.
  8. Если вы хотите измерить время работы скрипта, то лучше использовать $_SERVER[’REQUEST_TIME’] чем time()
  9. Заменяйте regex() на strncasecmp, strpbrk и stripos.
  10. Если функция принимает аргументы как в виде массива, так и отдельные переменные, то быстрее будет вызывать ее несколько раз, чем передавать сразу все значения в виде массива.
  11. switch() работает быстрее чем конструкции вида
    if(...) {...} elseif (...) {...} elseif (...) ...
  12. Подключите модуль апача – mod_deflate.
  13. Закрывайте неиспользуемые соединения с базой данных.
  14. Ошибки, которые возникают при работе скрипта, тоже замедляют работу. Старайтесь их избегать :)
  15. Не используйте функции при определении цикла. Пример:
    for ($i=0; $i < count($longlongarray); $i)

    Функция count() будет вызываться при каждой итерации массива.

  16. Инкремент (i++) для локальной переменной выполнится в два раза быстрее чем для глобальной.
  17. Инкремент для свойства объекта ($this->property++) выполняется в три раза медленнее чем для простой локальной переменной.
  18. Инкремент для неинициализированной переменной будет выполняться в 9-10 раз дольше чем для инициализированной.
  19. Одно только объявление глобальной переменной, которая в дальнейшем не используется, также замедляет работу (отнимает приблизительно столько же времени сколько и инкремент локальной переменной.
  20. Методы из классов-потомков вызываются быстрее чем из классов-предков. (Мораль – не создавайте без нужды громоздкую иерархию классов.)
  21. Вызов одной функции с передачей одного аргумента (тело функции пустое) занимает столько же времени сколько и 7-8 инкрементов для локальной переменной. Вызов такого же метода отнимет время равное 15 инкрементам.
  22. Если в строке не используются имена переменных, то лучше использовать одинарные кавычки, чем двойные (не тратится время на поиск переменных в строке).
  23. При выводе нескольких строк при помощи echo лучше перечислить их через запятую чем использовать конкатенацию.
  24. Веб-серверу Apache потребуется как минимум в два раза больше времени чтобы отдать по запросу скрипт php, чем статичную страницу html.
  25. PHP скрипты заново компилируются при каждом обращении к ним. Установите какое-нибудь кеширующее расширение на сервер (например, eAccelerator) – обычно это увеличивает производительность в 1-10 раз.
  26. Включайте кеширование везде где это возможно. Используйте такие программы как memcached – высокопроизводительная система кеширования, предназначенная для увеличения производительности динамических веб-приложений, которое достигается за счет снижения нагрузки на базу данных.
  27. Если нужно определить длину строки – используйте strlen(). Эта функция работает очень быстро потому что на самом деле она не выполняет подсчет символов. Она берет уже готовый результат из структуры zval (внутрення C-структура, которая используется для хранения переменных в PHP).
  28. Не используйте функции там, где можно использовать встроенные конструкции языка PHP. Например, вместо
    if (strlen($password) < 8 ) {
    	echo 'Your password is too short.';
    }

    можно написать:

    if (!isset($password{8})) {
    	echo 'Your password is too short.';
    }
  29. Постинкремент ($i++) намного медленнее чем преинкремент (++$i). Это связано с особенностями реализации языка PHP. Постинкремент создает одну временную переменную, в то время как постинкремент изменяет саму переменную непосредственно. Примечание: известно, что использование Zend Optimizer устраняет этот недостаток. Но, поскольку Зенд Оптимайзер установлен не на всех хостингах, лучше учесть этот момент во время создания скрипта…
  30. Не стоит использовать ООП там где без него можно обойтись. Создание объектов и обращение к их методам создают дополнительную нагрузку.
  31. Не стоит создавать классы в качестве контейнеров для данных. Массивы прекрасно справляются с этой задачей.
  32. Не создавайте слишком много методов (хотя само по себе количество методов не отражается на времени обращения к каждому отдельному методу – быстрее будет работать тот скрипт, который использует меньшее количество вызовов.
  33. По возможности используйте те функции, которые уже есть в языке PHP.
  34. Если в вашем коде есть функции, которые сильно нагружают систему, подумайте – может есть смысл переписать их на C и подключить как расширение?
  35. Используйте профайлер во время отладки кода. Он покажет вам самые узкие места в вашей программе.
  36. Установите mod_gzip. Этот модуль Апача сжимает данные на лету и может уменьшить объем передаваемых данных на 80%

Фух, хватит на сегодня :)

Если вам понравился этот сайт, вы можете подписаться на rss

Отзывы: 11 комментариев

  • Victor
    12 Март 2009 в 15:50

    Cпасибо! Напечатал на принтере и повесил на стенку :-)

  • гoлЬeтти
    05 Апр 2009 в 19:31

    Хм… что-то у меня ссылка не открывается, которую указали. Это у всех так?

  • admin
    09 Апр 2009 в 23:37

    Какая именно? В этом посте нет ни единой ссылки, товарищ спамер! :)

  • ls
    24 Авг 2009 в 6:47

    Материал супер, спасибо. а вот читать тяжело, еле осилил, добавьте line-height и верните показ цифр у UL.

  • Alex
    25 Авг 2009 в 0:12

    Интересует этот момент
    if (!isset($password{8}))
    точнее именно $password{8}
    где о таких методах проверки прочитать ? :)

  • Руслан
    25 Авг 2009 в 0:58

    ls, спасибо за замечание. после установки на блог нового шаблона забыл проверить верстку старых постов…

  • Руслан
    25 Авг 2009 в 1:07

    Alex, $строковая_переменная{} работает так же как и $строковая_переменная[], т.е. осуществляет доступ к отдельным символам строки как к элементам массива. Но такую запись использовать уже не рекомендуется (deprecated для PHP>=5.3.0)

  • Alex
    25 Авг 2009 в 21:40

    Спасибо :) .

  • Павел
    25 Ноя 2009 в 7:48

    пункты 3 и 23 идентичны по смыслу

  • Стас
    25 Янв 2010 в 12:38

    4 и 15, 12 и 36 – одно и то же.
    учитывая что 3 и 23, которые тоже одинаковы, то можно вычесть 3 пункта, выбрав из них самые удачные :)

  • quo
    17 Фев 2010 в 16:19

    Пункт 29:
    Постинкремент создает…, в то время как постинкремент изменяет…
    исправьте пост инкремент на преинкремент где надо.

Ваш отзыв

Имя (*)

E-mail (*)

Сайт

Сообщение

Архивы

Реклама