Повышаем производительность PHP: 4 приема
альтернативные php-функции, повышающие скорость выполнения задач
Обычно, я пишу PHP-код, используя очевидные и наиболее популярные функции, хотя бы для того, чтобы избежать возможных неявных ошибок и проблем. Однако, я считаю, что альтернативный подход для решения некоторых задач является разумным решением, хотя бы потому, что позволяет значительно сократить время их выполнения.
В этой статье представлены альтернативные функции, которые полезны для разработчиков, занимающихся поиском различных методов повышения производительности своих проектов.
Итак, давайте посмотрим: какие популярные PHP-функции могут быть заменены более производительными альтернативами.
Все перечисленные ниже примеры были протестированы на локальном сервере с PHP 7.4
Удаляем дубли
Допустим, у нас есть большой массив, который содержит повторяющиеся записи. Наша цель: оставить только уникальные записи, удалив дубли.
Традиционное решение
array_unique($array);
Альтернативное решение
array_keys(array_flip($array));
Производительность
Я создал массив из 4-х миллионов записей, содержащий около 3-х миллинов дублей. Посмотрим на результат:
Функция | Времы выполнения |
---|---|
array_unique | 787,31 мс |
array_keys array_flip | 434.03 мс |
В данном примере альтернативный подход оказался быстрее в 1,8 раза (44,87%), в среднем он был быстрее в 1,5 раза (30%).
Особенности
Альтернативное решение можно применить только к простым, одноуровневым массивам, так как функция array_flip
заменяет ключи значениями.
Получаем случайный элемент массива
Итак, у нас есть большой массив. Наша цель: получить случайный элемент этого массива.
Традиционное решение
array_rand($array);
Альтернативное решение
$array[mt_rand(0, count($array) - 1)];
Производительность
Я создал массив из 5-и миллионов записей. Посмотрим на результат:
Функция | Времы выполнения |
---|---|
array_rand | 25,99 мс |
mt_rand | 0,95 мс |
В данном примере альтернативный подход оказался быстрее в 27,3 раза (99,97%), в среднем он был быстрее в 8 раз (87%).
Особенности
Полученный результат несколько обескураживает, так как функция mt_rand
является реализацией поиска случайных чисел методом вихря Мерсенна (Mersenne Twister), а, начиная с PHP версии 7.1, алгоритм встроенной функции поиска случайных чисел был заменен именно на метод Мерсенна.
Буквенно-цифровые симоволы
Довольно часто возникает ситуация, когда нужно проверить строку на содержание только буквенных и цифровых символов.
Традиционное решение
preg_match('/[a-zA-Z0-9]+/', $string);
Альтернативное решение
ctype_alnum($string);
Производительность
Я создал строку, которая содержит более 100 тысяч буквенно-цифровых и иных символов. Посмотрим на результат:
Функция | Времы выполнения |
---|---|
preg_match | 15,39 мс |
ctype_alnum | 2,06 мс |
В данном примере альтернативный подход оказался быстрее в 7,5 раз (86,59%), в среднем он был быстрее в 4 раза (76%).
Особенности
Сходный результат получен при проверке на содержание только буквенных символов с функцией ctype_alpha()
и на содержание только цифровых символов с функцией ctype_digit()
.
Замена фрагмента строки
Традиционное решение
str_replace('a', 'b', $string);
Альтернативное решение
strtr($string, 'a', 'b');
Производительность
Я создал массив из 5-и миллионов случайных строк. Посмотрим на результат:
Функция | Времы выполнения |
---|---|
str_replace | 676,59 мс |
strstr | 305,59 мс |
В данном примере альтернативный подход оказался быстрее в 2,2 раза (54,83%), в среднем он был быстрее в 2 раза (51%).
Дополнительные факторы, повышающие производительность
Ниже я перечисляю несколько моментов, которые, как я считаю, позволяют повысить производительность любого проекта на PHP:
- JSON - приоритетный формат при выборе между JSON и XML,
- переменные следует объявлять до начала итераций,
- не включайте функции в тело заголовка цикла (например:
for ($i=0; $i
, в таком случае count()
будет выполняться с каждой итерацией), - оператор
switch
лучше, чем несколькоif
-
require
иinclude
лучше, чемrequire_once
иinclude_once
(така обеспечивают корректное кеширование).
Все вышеперечисленные пункты не являются аксиомой и отражают лишь мое субъективное мнение. Существует много рассуждений по поводу преждевременной оптимизации. И я согласен, что производительность “боевого” проекта зависит от узких мест, например, от времени выполнения запросов к базе данных. Но в тех случаях, когда есть более быстрые и понятные альтернативные решения (как в примере с регулярным выражением), их нужно использовать.
Для тестирования функций использовалось отличное приложение от Bart van Hoekelen.
Спасибо за внимание.
Написано по материалам статьи Andreas “4 PHP Tricks to Boost Script Performance”.