__DIR__ vs dirname( __FILE__ )

Вызов константы всегда должен быть быстрее, чем вызов функции, верно? В PHP есть два разных способа получить каталог, в котором в данный момент находится файл. __DIR__ — магическая константа, добавленная в PHP в версии 5.3. В официальной документации PHP конкретно указано: «Это эквивалентно dirname(__FILE__) ». Эквивалентность по возврату не обязательно означает эквивалентность по производительности, поэтому я решил проверить производительность обоих по паре переменных.

Методология тестирования

При выполнении большого количества тестов я обнаружил, что travis-ci может быть большим помощником. Вы можете определить матрицу тестов, которые хотите запустить, в качестве матрицы тестирования, а затем использовать результаты. Поэтому я настроил репо для своих тестов. Репозиторий состоит из четырех основных частей:

  1. Генератор файлов, который создает код, на котором я буду запускать тест производительности.
  2. Сценарий запуска теста, который запускает настоящие тесты.
  3. Файл travis.yml для определения матрицы моих тестов
  4. Файлы, используемые для фактического теста. Это не связано, там 400 000 файлов. Генератор показывает их.

Мой тест вызывает функцию, которую я ищу по 100 000. В одном прогоне все файлы находятся в одном каталоге, а в другом — по одному файлу в каждом каталоге. Я хотел исключить возможность того, что один каталог может повлиять на этот вызов.

Я провел этот тест на шести версиях PHP: 5.6.40, 7.0.33, 7.1.27, 7.2.15, 7.3.9 и 7.4-dev. Каждый тест выполнял 650 прогонов, и я посмотрел на

пользовательское время для каждого из этих запусков. Это означает, что я вызывал как __dir__ , так и dirname( __file__ ) по 130 000 000 раз каждый. Затем я взял время для каждого из этих запусков и посмотрел на этот максимальный (самый медленный) запуск для каждого и 95% времени (среднее между 618-м и 619-м самым медленным), чтобы исключить любые крайние случаи. В целом, результаты между максимумом и 95% аналогичны.

User

 – это время, затрачиваемое ЦП на выполнение кода пользовательского режима (вне ядра)  внутри  процесс. Это только фактическое время ЦП, используемое при выполнении процесса. Другие процессы и время, которое процесс тратит заблокированным, не учитываются в этой цифре.

Переполнение стека

__DIR__ vs имя_каталога (__FILE__) Результаты тестов

Производительность 95%

Сценарий 5,6 7,0 7,1 7,2 7,3 7,4
каталог (1 папка) 1,4 2,76 2,08 2,51 2,27 1,3615
каталог (много папок) 1,38 2,29 2,55 2,3615 2,65 1,57
имя_директории( 1 папка) 1,5815 2,27 2,7415 3,24 2,41 1,5215
имя_каталога (много папок) 1,68 2,29 2. 0815 3,29 2,6815 1,87

В целом результаты показывают, что __dir__ обычно работает быстрее, но редко намного быстрее. Учтите, что при самом медленном запуске (с использованием PHP 7.2 и вызовом

dirname( __FILE__ ) для нескольких папок) каждый вызов занимал 0,0000329 секунд. Самый быстрый бег был на 2 стотысячных секунды быстрее. Это такая микрооптимизация, что, если не считать экстремальных масштабов, маловероятно, что вы когда-нибудь заметите разницу. При этом в большинстве версий PHP __DIR__ быстрее.

Итак:

__dir__ или имя_каталога ?

В конце концов, производительность __DIR__ немного лучше, но, что более важно, я думаю, что он понятнее и легче читается. Итак, я в команде __dir__ , но производительность — это только бонус.

Если у вас есть другое мнение или вы считаете, что мою методологию тестирования можно улучшить, сообщите мне об этом в комментариях ниже.

#48082 (Заменить `dirname(__FILE__)` на `__DIR__` (улучшение производительности, масштабное исправление)) – WordPress Trac 055

Сообщено автор: айешраджаны Владелец: СергейБирюков Веха: 5.4 Приоритет:
нормальный Строгость: незначительный Версия: Компонент: Общий Ключевые слова: имеет-патч нуждается в тестировании Фокусы: производительность, стандарты кодирования
Копия:

В PHP 5. 3 добавлена ​​магическая константа __DIR__ , которая совпадает с dirname(__FILE__) . Поскольку имя_каталога() является вызовом функции, каждый раз, когда мы используем имя_каталога(__FILE__) 9, это может иметь накладные расходы на вызов функции.0004 вместо __DIR__ .

Теперь, когда нам требуется PHP 5.6 как минимальная версия, мы можем отказаться от вызовов

dirname() в пользу __DIR__ .

Приложен массивный патч, который заменяет все такие вызовы магической константой. Я проверил источник на предмет дальнейших вхождений, и теперь мы чисты.

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

Спасибо.

Приставки (5)

48082-1.patch​ (83,8 КБ) — добавлено ayeshrajans 4 года назад.
48082.