Почему производительность PHP strtolower настолько варьируется?

Я сделал некоторое профилирование на сайте и обнаружил, что вызовы strtolower заняли неожиданно много времени.

Контекст

function __autoload($class_name) { 
 require_once('app/model/' . strtolower($class_name) . '.php'); 
}

И результат - _0.0092 → ___ autoload() C:\xxx\config.php: 0_ 0.0093 → strtolower() C:\xxx\config.php: 77 0.0101 → require-once (C:\xxx.php) C:\xxx\config.php: 77 Я видел это в нескольких местах в файле трассировки.

Затем я попробовал функцию в следующем контексте

for($i=0;$i<100;$i++) { 
 strtolower('SomeStRIng' . $i) 
}

И результат был 0.0026 → strtolower() C:\xxx\index.php: 53 0.0027 → strtolower() C:\xxx\index.php: 53 0.0027 → strtolower() C:\xxx\index.php: 53 0.0027 → strtolower() C:\xxx\index.php: 53

Между ними существует заметная разница. Это, конечно, не большой, но я все еще смущен.

2 ответа

У вас слишком маленькие тесты, на слишком маленьких данных. Вы никогда не получите согласованные данные, так как другие системные факторы (например, скорость/загрузка процессора) будут намного больше.

Ваш первый тест связан с диском. Опускание случая (надеюсь, разумно) короткой струны по существу мгновенно или, по крайней мере, измеряется в микросекундах. Нахождение диска для поиска/загрузки/разбора файла займет порядка миллисекунд. Вы пытаетесь обнаружить разницу в чем-то, где часть, которую вы не беспокоите, занимает в 1000 раз дольше. т.е.: strtolower overhead - ошибка округления.

Ваш второй тест, будучи чисто cpu/memory bound, также слишком короткий, чтобы быть практичным. Вы не можете быть уверены, что выполнение 100 конкатенаций строк (и соответствующего распределения памяти) не приведет к подавлению фактического нижнего индекса. Лучшим тестом было бы предустановить ряд строк с примесями (несколько сотен или тысяч из них), а затем циклически перебирать этот массив и strtolower в seuqnce. Таким образом, вы устраняете как можно больше накладных/нерелевантных кодов, и, надеюсь, получите более согласованные данные.


Какой профайлер вы использовали? XDebug?

Я бы заподозрил, что это проблема с профилировщиком, поскольку вы демонстрируете довольно значительную разницу. Смотрите, если это профили по-разному...

function __autoload($class_name) { 
 $file=strtolower($class_name);
 require_once('app/model/' . $file . '.php'); 
}

licensed under cc by-sa 3.0 with attribution.