Оптимизация больших PHP-приложений 05/07/07
Преждевременная оптимизация – корень всех бед.
– Дональд Кнут (Donald Knuth)
С другой стороны, мы не можем игнорировать эффективность.
– Йон Бентли (Jon Bentley)
Благодаря повсеместному распространению PHP5 (с его переработанным ОО ядром) у разработчиков появилась возможность и желание писать правильный ОО-код. У многих это даже превращается в самоцель. Книжек про паттерны и всех китов ООП написано много, приложения на PHP становятся огромными - берись и делай. Да и куда теперь без разделения логики, представления и доступа к данным. Получается, что с вопросами производительности разработчик сталкивается только в конце решения задачи в целом. И, как правило, ее начинает не хватать в сценариях по обработки тысячей записей.
Я хочу дать несколько полезных советов как писать более эффективный код в самом начале, помня, что PHP все же скриптовый процедурный язык. Советы я расцениваю ни как преждевременную оптимизацию, а как стандартную работающую рекомендацию уровня: «в С++ используйте префиксную форму инкремента». Большинство рекомендаций еще раз озвучивание общеизвестных вещей.
Общие рекоммендаци по оптимицации любых PHP:
- Использовать стандартные функции и алгоритмы PHP, а не писать собственные алгоритмы (в PHP это прямо влияет на скорость.). Примеры:
- Не перебирать ассоциативный массив руками если есть конструкция: foreach ($arr as $key => $val).
- Не разбирать строки руками и не склеивать их если есть: implode/ join.
- Использовать специальные библиотеки для работы с БД (например ) и прочим, а не писать собственные (cм. заключение). Это, как правило, эффективней и безопасней.
Специальные рекоммендаци по оптимицации бОльших PHP:
- Если в цикле с тысячей итераций каждый раз объект создается заново ($obj = new Shape()) лучше вынести его создание на уровень выше, либо сделать его статическим, а в класс добавить метод сбрасывания содержимого.
- Если функции передается больше 2-3 параметров или после создания объекта нужно установить множество внутренних полей следует обернуть необходимые данные в массив и разом передать функции/объекту:
$arr= array('FName' => $this->fName, 'LName' => $this->lName, 'Year' => $this->year) $obj = new Person($arr);
- Еще не проинициализированные переменные лучше устанавливать в false. Так их проще использовать в условных операторах.
Заключение
Здесь хочется еще раз остановиться на самых важных рекоммендация общего характера.
- Только когда уверены на 200% что ваша библиотека/функции будут быстрее работать, с БД. И вам действительно необходим выигрыш производительности именно в этом месте – используйте свою разработку. Обязательно не забудьте использовать mysql_real_escape_string.
- Не пытайтесь оптимизировать, то что как вам кажется работает медленно, но у вас нет точных тестовых результатов, либо данных профайлера.
Более подробно вопросы разработки больших систем с использованием ООП осещены в замечательной книге Джоржа Шлосснейгла "Профессиональное программирование на PHP" Вильямс, 2006 г.
От себя добавлю: не нужно вычислять размер массива его перебором. При наполнении массива автоматически изменяется срытое поле count, которое затем можно получить функцией count($arr)