Pull to refresh

Серия 50+ советов по оптимизации PHP кода. «За» и «против» такой оптимизации. Первые 10 советов.

Reading time 6 min
Views 21K
Original author: HM2k
Это перевод первых 10-ти советов статьи по оптимизации PHP кода. На хабре есть перевод более старой версии статьи — 40 советов по оптимизации вашего PHP-кода

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

Пишу по частям, иначе получится очень много материала сразу.

Это моя первая статья на хабре, надеюсь она получилась интересной.


Замечаняе:
В этой статье я часто не соглашаюсь с советами из оригинальной статьи. Мои вставки выделены курсивом. И стараюсь приводить аргументы, почему я соглашаюсь или не соглашаюсь с советами по оптимизации.

Я не отвечаю за точность тестов, сам я не проводил тесты. Хотя бы потому что для большиства советов разница очень незначительна для большинства возможных случаев, и ключевую роль играют другие факторы — читабельность, масштабируемость, гибкость. И финансовая оправданность.

Я не претендую на роль эксперта, и не считаю свои комментарии к советам прямыми указаниями к действиям. А тем более не призываю пользоваться советами оригинальной статьи.

Основная цель, почему я решил сесть и написать эту статью — попытка разрешить споры о нужности оптимизации, «экономии на спичках».

Что считаю для себя( потому что где то вычитал, на основе опыта и т.п.) и хочу привести в виде списка:

1. Не стоит делать оптимизацию досрочно, на этапе разработки
2. Не стоит экономить на спичках
3. Обращать внимание впервую очередь на наиболее узкие места, и где оптимизация будет наиболее эффективна
4. Ваш код должен быть читабелен, масштабируем, гибок. (но в зависимости от поставленной задачи, требования могут быть другие).

Примечания:
— Автор использует для названия всех ссылок текст "[Citation]", однако часть ссылок ведут на тесты, доказывающие утверждения о производительности, к примеру, той или иной конструкции, а часто ссылок на полезные ресурсы. Я буду называть ссылки, ведущие на тесты "[тест]", а ведущие на полезные ресурсы "[полезная информация]", а на статьи соответственно "[статья]".

— Свои дополнения я буду выделять курсивом.

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

Все что я дополнил к оригиналу, это мой опыт, мои знания, которыми и делюсь.

Читателям: Это статья адресована впервую очередь не гуру веб-разработки, а тем кто только набирается опыта. Но надеюсь что она будет интересна и профессионалам.

Поехали :)

1. echo быстрее чем print. [тест]

Да и писать на одну букву меньше. Но скорее этот совет для общего развития. Большинство программистов используют echo. Прирост производительности минимален. И в серьезных проектах echo редко встречающаяся конструкция. Потому что вывод как правило сначала собирается, а потом выбрасывается.

2. Строки заключенные в одинарные кавычки ', а не в вдвойные " быстрее, потому что PHP ищет переменные внутри строк, заключенных в двойные кавычки. Заключайте строки в одинарные кавычки, когда в ней нет переменных. [статья]

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

3. Используйте sprintf вместо переменных, заключенных в двойные кавычки. Это примерно в 10 раз быстрее. [тест]

Скорей всего это по причине того, что если использовать sprintf, то PHP обращается к С-функции sprintf. Что само собой быстрее чем если разбор строки будет производить сам PHP, написанный на С. Однако я не думаю что такой код будет достаточно легко воспринимаем. Возможно такое имеет смысл на очень высоконагруженных проектах, где ведется очень много работы со строками, и использование sprintf может дать ощутимый выйгрыш в производительности. Но я не представляю себе таких проектов. Обычно все валится в других местах.

4. Передавайте в echo несколько параметров, вместо того, чтобы использовать конкатенацию строк. [статья]

Логично что это работает быстрее, за счет того что нет конкатенации, которая требует времени. А параметры один за другим выбрасываются в выходной поток. Насчет читабельности, мне лично множественные параметры читать удобней, чем конкатенацию, но возможно не всем так:

echo $a, 'text', $b, 'more text'; // множественные параметры
echo $a . 'text' . $b . 'text'; //конкатенация


По примечанию eyes, по результатам теста phpbench.com, конкатенация константных строк для echo работает быстрее, чем если передавать их множественными параметрами

5. Не используйте вычисления числа элементов массива, длины строки и т.п., для определения последней итерации цикла в самом цикле. Установите максимальное значение для цикла for перед ним. Например: for ($x=0; $x < count($array); $x), вызывает count() при каждой итерации, используйте $max=count($array); перед циклом. ссылка [тест]

Это давно известный факт. Тест показывает разницу в производительности в 10 раз. Если имеет место довольно большой массив данных, или подобные вычисления происходят часто, стоит задуматься. На читабельность не влияет никак.

6. Разыменовывайте или обнуляйте ваши переменные чтобы освободить память, особенно если это большие массивы. [полезная информация]

Это касается и удаления из буфера результатов запросов к базе данных к примеру. Но удаление всех уже неиспользуемых переменных сильно снижает читабельность кода. Использование переменных везде где можно тоже не признак хорошего стиля программирования:
// так писать не стоит
$time = time();
$login = $_SESSION['login'];
$hash = md5($login . $time);

// если можно записать так
$hash = md5( $_SESSION['login'] . time() );


в том случае если эта конструкция используется один раз. Так глаз воспринимает код лучше. Потому что он в одну строчку. Но увлекаться тут не стоит, так как это может опять же привести к нечитабельности. Но это оступление.
Оптимизацию по освобождению памяти от ресурсов(переменные, результаты запросов к базе и т.п.) стоит производить уже на законченном приложении под нагрузкой, и только если это действительно большие ресурсы. Тогда и можно оценить пользу от такой оптимизации.


7. Избегайте магических методов, таких как __get, __set, __autoload [полезная информация]

… А также __call, __toString… Не оправданно. Так как к примеру перегрузка сильно упрощает разработку, и снижает объемы кода. Насчет __autoload это спорный момент. По своему опыту, это удобно. Но в тоже время, если приходит новый человек на проект, для него было бы наглядней прямые инклуды, чем использование __autoload(), и соотственно ему потребовалось бы меньше времени чтобы влиться в проект.

8. По возможности используйте require() вместо require_once(). [статья]

Весьма неоправданная экономия. С require вместо require_once гораздо больше вероятности подгрузить уже подгруженный файл, что явно не уменьшит время выполнения кода. Да и заставляет излишне беспокоится о том, не подружен ли где либо уже этот файл, что особенно актуально в работе в команде, и сильно тормозит разработку

9. Используйте полные пути в include(_once) и require(_once), уменьшая тем самым время на разрешение путей OS. [статья]

Это разумно по другой причине. Когда из скрипта который лежит не в корне document_root, нужно подгрузить другой скрипт, который лежит либо выше, либо гораздо ниже. Это позволяет не заботиться о расположении скриптов в проекте относительно друг друга при их подключении. Но для путей лучше определить константы, используя $_SERVER['DOCUMENT_ROOT'], или getcwd(). Также иногда бывает сбой путей в настройках php.ini, что PHP, попросту не ищет скрипты в document_root, и такая методика позволяет обезопаситься от этого. А использование разных констант для разных папок позволяет увеличить читабельность кода. Например:
TEMPLATES_DIR
CORE_DIR
MODULES_DIR



10. require() и include() идентичны во всех отношениях за исключением того, что require останавливает выполнение скрипта, в том случае, когда подключаемый файл не найден. Разница в скорости работы минимальна.

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

Файлы, подключенные через require подключает файлы на начале этапа выполнения, а include во время интерпретации. И если include находится внутри блока if, и условие не выполнилось, то файл не будет подключен.


Остальные 40+ советов будут в ближайшем будущем.
Tags:
Hubs:
+44
Comments 142
Comments Comments 142

Articles