Измерение реального времени парсировки имён переменных внутри строк.

ONK

Пассивист PHPСluba
Измерение реального времени парсировки имён переменных внутри строк.

Привёл от нечего делать серию тестов, результаты как мне кажется интересны.

Сначала остановлюсь на методике тестирования, Чтобы потом никто, не аргументировано, не говорил что методика неправильная... Если считаете неправильной, то что конкретно?..

Если стоит вопрос об измерении времени парсировки переменных в закавыченных двойными кавычками строках, то именно это и надо измерять. А не пытаться имитировать реальное приложение. Должен быть получен максимально "чистый" результат, из которого каждый сам сделает выводы..

Для получения чистого результата, предварительно запускаем калибровочный цикл с простейшим действием присваивания одной переменной строкового значения в 1 символ из другой переменной. Время исполнения 100000 итераций этого цикла записываем в калибровочную переменную, для последующего вычисления "чистого" времени.

PHP 4.1
Apache 1.3...
W2k

PHP:
$a = 'thyyjfnjjdfgtnbvk';
$b = 'kyiiyijgnmvbdgft';
$c = 'a';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c;
}
$calibr = $mark10->current_time();
На моей машине время исполнения калибровочного цикла 127милисекунд

После этого на основе этого - же цикла создаём тестовые циклы с различными вариантами тестирования работы переменных и строк:

1. Измерение скорости конкатенации одной дополнительной переменной:
PHP:
$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c.$a;
}
echo $mark10->current_time()-$calibr,'<br>';
Результат - чистое время извлечения значения из одной переменной и конкатенации к чему-то составляет 63милисек.

Конкатенация двух переменных (дополнительно ещё и $b) происходит за 119милисекунд.

Что подтверждает правильность методики тестирования.

2. Измерение скорости парсировки и конкатенации короткой строки, в которой находится одна переменная:
PHP:
$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."dsgder$a";
}
echo $mark10->current_time()-$calibr,'<br>';
Результат - Чистое время парсировки и конкатенации составляет 266милисекунд. После следующего теста можно вычислить условное время парсировки переменной в строке.

3. Измерение скорости простой конкатенации строки и переменной.
PHP:
$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."dsgder".$a;
}
echo $mark10->current_time()-$calibr,'<br>';
Результат - Общее чистое время конкатенации строки и переменной составляет 103милисекунды.

Из этого следует несколько выводов:
Чистое время парсировки переменной в строке из 8 символов составляет 166милисекунд.
Чистое время конкатенации строки к чему-то составляет ~40милисекунд.
Удивительно, но тест подтвердил последнюю прикидку с 40милисекундами. (Полный исходник теста в конце темы.)

4.Измерение чистого времени парсировки и конкатенации строки из 16символов и с одной переменной.
PHP:
$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."dsgderfthujbkb$a";
}
echo $mark10->current_time()-$calibr,'<br>';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."dsgder$a'fgtfgth";
}
echo $mark10->current_time()-$calibr,'<br>';
Результат - Чистое время парсироваки и конкатенации 286 -343 (в зависимости от того с какой стороны от переменной добавлять дополнительные знаки в строку, видимо, связано с алгоритмом поиска). Чистое время парсировки 186 - 240 миллисекунд. (240 - 166 = ~ 60 интересная цифра. но не о чём не говорит).

5 Измерение чистого времени конкатенации строки с двумя переменными внутри
PHP:
$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."ertdfgsrtyr$a%fhdtu truyrety$b&ytre";
}
echo $mark10->current_time()-$calibr,'<br>';
$mark10->start();
Результат - Чистое время парсировки и конкатенации 585милисекунд.

6. Измерение чистого времени конкатенации переменных и строк, аналогичных пункту 5, но без парсировки.
PHP:
Результат Чистое время 245 ~= (60 + 60 + 40 + 40)



Помимо всех вышеприведённых тестов я провёл ещё серию тестов, из которой понял алгоритм поиска переменных внутри строки. Он таков - ПХП анализирует строку на наличие знака "$" если знак обнаружен, запускает процедура парсирвки строки на фрагменты, разделённые знаками (в том числе и пробела, но не буквы и не цифры). Все фрагменты строки, разделённые знаками парсируются на наличие в них знака "$", если он есть, то именем переменной считается участок строки от знака $ до конца текущего фрагмента. Это подтверждает также то, что возникают необъявленные переменные длинной именно до конца фрагмента, хотя в глобальной видимости есть переменная с более коротким именем, входящим в этот фрагмент сразу после знака $.
Этот алгоритм явно не оптимален, эффективнее было бы, найдя в строке символ $ дойти до знака ограничивающего фрагмент, посчитать выделенный участок строки именем переменной и поискать её среди объявленных..., затем поискать в оставшейся части строки ещё один символ $, если есть, - рекурсивный вызов если нет, - выход из парсировки.

Получилась целая научная работа :cool:


Мои выводы:
Использование переменных внутри "строк" оправдано только при составлении SQL запросов к базе данных. Читабельность запроса повышается, а их количество в нормальных приложениях редко превышает 2-х десятков.

PHP:
<?php
class onk_Time_marker{
	var $s_m;

	function onk_Time_marker(){
		$prom = explode(" ",substr(microtime(),2));
		$this->s_m = $prom[1].".".$prom[0];
	}
	
	function start(){
		$prom = explode(" ",substr(microtime(),2));
		$this->s_m = $prom[1].".".$prom[0];
	}

	function current_time(){
		$prom = explode(" ",substr(microtime(),2));
   		$m_s = $prom[1].".".$prom[0];
		$time = $m_s - $this->s_m;
		return round($time,11);
	}
}
$mark10 = new onk_Time_marker();

$a = 'thyyjfnjjdfgtnbvk';
$b = 'kyiiyijgnmvbdgft';
$c = 'a';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c;
}
$calibr = $mark10->current_time();

echo 'Калибровка поправки ',$calibr,'<br>';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c.$a;
}
echo $mark10->current_time()-$calibr,'<br>';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c.$a.$b;
}
echo $mark10->current_time()-$calibr,'<br>';


$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."dsgder$a";
}
echo $mark10->current_time()-$calibr,'<br>';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."dsgder".$a;
}
echo $mark10->current_time()-$calibr,'<br>';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."dsgder";
}
echo $mark10->current_time()-$calibr,'<br>';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."dsgderfthujbkb$a";
}
echo $mark10->current_time()-$calibr,'<br>';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."dsgder$a'fgtfgth";
}
echo $mark10->current_time()-$calibr,'<br>';


$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."ertdfgsrtyr$a%fhdtu truyrety$b&ytre";
}
echo $mark10->current_time()-$calibr,'<br>';


$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."ertdfgsrtyr".$a."%fhdtu truyrety".$b."&ytre";
}
echo $mark10->current_time()-$calibr,'<br>';

//Анализ алгоритма парсировки строк.

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."ertdfgsrtyr$a hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh";
}
echo $mark10->current_time()-$calibr,'<br>';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."ertdfgsrtyr$a hhhhh hhhhhhh hhhhhhh hhhhhh hhhhh hhhhh hh hhhhhh";
}
echo $mark10->current_time()-$calibr,'<br>';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."ertdfgsrtyr hhh^hhhhh^^hhhhh^hhhhh^hhh^hhhh^hhhh^hhhh^hhh^hhhh hbui ftyi yy gyyt 6 5  5gdf%gkuygku*huyg&bhjv*jhbjb#jkghuy#jkbvhu@jhgkj!hvgh(njbku)";
}
echo $mark10->current_time()-$calibr,'<br>';

$mark10->start();
for($i=0;$i<100000;$i++){ 
    $m = $c."ertdfgsrtyr$a hhh^hhhhh^^hhhhh^hhhhh^hhh^hhhh^hhhh^hhhh^hhh^hhhh hbui ftyi yy gyyt 6 5  5gdf%gkuygku*huyg&bhjv*jhbjb#jkghuy#jkbvhu@jhgkj!hvgh(njbku)";
}
echo $mark10->current_time()-$calibr,'<br>';
?>
 

ForJest

- свежая кровь
FreeBSD, PHP 4.2.3
Калибровка поправки 0.25804209709
0.10913586617
0.33014285565
0.56837892533
0.21606993675
0.07258594036
0.40332293511
0.61005187035
1.20325398445
0.42115092278
0.57955181599
1.21458089352
0.16801595688
2.84015691281

Win98, PHP 4.1.2
Калибровка поправки 0.20630204678
0.10940301418
0.22713601589
0.49917590618
0.17481195926
0.06631195545
0.52859294414
0.63716590404
1.02341687679
0.45022201538
0.74625504016
1.65732896328
0.20602405071
4.10049796104
----------------------
Провалы наблюдаются в обоих средах обитания :)
Результаты последнего теста особо удручающие....
Ведь парсинг строки получается происходил целых 0,000041 секунды ;)
----------------------
Хотя довольно познавательно - спасибо, ONK :)
 

ONK

Пассивист PHPСluba
Да ты что говориш,,, ууу, Зато это "чистый замер" ;)
 

Crazy

Developer
Re: Измерение реального времени парсировки имён переменных внутри строк.

Автор оригинала: ONK
Если считаете неправильной, то что конкретно?..
Вот это:

не пытаться имитировать реальное приложение
Лично меня просто не интересует "чисто академический" разультат. Меня интересует измерение скорости именно применительно к типичным фрагментам кода.

Просто ответ не твой вопрос. :)
 

ONK

Пассивист PHPСluba
Показательна именно последняя строка и предпоследняя. Если пхп не видит в строке символа $ (это видимо обнаруживается на стадии конвертирования спецсимволов) он её подробно не парсит.
 

Crazy

Developer
Автор оригинала: ONK
Да ты что говориш,,, ууу, Зато это "чистый замер" ;)
Сравнение двух РАЗНЫХ версий PHP можно называть "чистым замером" разве что в качестве шутки...
 

ONK

Пассивист PHPСluba
Меня интересует измерение скорости именно применительно к типичным фрагментам кода.

Всё очень просто, если есть запрос к БД, можно забыть про оптимизации :)

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

ForJest

- свежая кровь
Сравнение двух РАЗНЫХ версий PHP можно называть "чистым замером" разве что в качестве шутки...
Могу еще несколько серверов привести. Но я тестил не версии, а платформы.
 

ONK

Пассивист PHPСluba
Автор оригинала: Crazy
Сравнение двух РАЗНЫХ версий PHP можно называть "чистым замером" разве что в качестве шутки...
Чистый замер, это замер с вычитом времени работы языковой конструкции не относящейся к измеряемому времени конкатенации и парсировки строк. Имеется в виду чистое время парсировки. А версия ПХП тут непричём.
 

ONK

Пассивист PHPСluba
4.3 Наверное будет интересно..

Вот мой замер.

Калибровка поправки 0.12949299812
0.06246805191
0.11933004856
0.25562298298
0.10238707066
0.04832100869
0.27973294258
0.33988308907
0.56265604496
0.24987900257
0.38434100151
0.90358102322
0.09281396866
0.09293997288
2.2865459919
 

ONK

Пассивист PHPСluba
У меня результаты удивительно хорошо и стабильно повторяются.
 

Crazy

Developer
Автор оригинала: ForJest
Могу еще несколько серверов привести. Но я тестил не версии, а платформы.
Ты сравнивал результат работы программы A на платформе X и результат работы B на Y. Смысла в этом нет.

Сравнение имело бы смысл, если бы различался ОДИН параметр, а не два.
 

Crazy

Developer
Автор оригинала: ONK
А версия ПХП тут непричём.
Ага. Сравним время парсинга PHP 1.0 и PHP 4.3 и будем делать далекоидущие бессмысленные выводы. См. мой ответ ForJest'у.
 

Crazy

Developer
Автор оригинала: ONK
Всё очень просто, если есть запрос к БД, можно забыть про оптимизации :)
Тебе просто не попадались криво написанные regexp'ы. :) Некотопые шедевры делают несущественным время исполнения запроса... :)
 

ONK

Пассивист PHPСluba
Автор оригинала: Crazy
Ты сравнивал результат работы программы A на платформе X и результат работы B на Y. Смысла в этом нет.

Сравнение имело бы смысл, если бы различался ОДИН параметр, а не два.
Надо ещё вспомнить про процессор, они тоже наверняка разные. Тут важна схожесть поведения приведённых тестов + возможность вычислить чистое время парсировки или время конкатеначии различных строк и переменных, на конкретной машине с конкретным процессором ПО и операционкой.

Кстати в приведённом мною результате теста одна сторока (предпоследняя) лишняя.

+ в тескте описания теста вот этот фрагмент:
Результат Чистое время 245 ~= (60 + 60 + 40 + 40)
следует читать так:
Результат Чистое время 245 ~= (60 + 60 + 40 + 40 + 40)
Было протестировано две переменные(60) + три строки (по 40милисекунд).
 

ForJest

- свежая кровь
Гы :) Версия апачи тоже имеет значение? :)
Я априори предполагаю что в винде и Unix PHP работает с разной скоростью. Поэтому все результаты тестирования на Win нужно тестить и на Unix - проблема может отпасть сама собой.

FreeBSD PHP 4.1.2.
Калибровка поправки 0.22575306892
0.09477591515
0.19483089447
0.36242890358
0.1656960249
0.07865095139
0.36122989655
0.44194793702
0.71978795529
0.37329792977
0.48063194752
1.06118190289
0.14128184319
2.44849097729

FreeBSD PHP 4.3.0 (1-й результат)
Калибровка поправки 0.19450891018
0.11573302746
0.34813809395
0.82964515686
0.22085309029
0.17613208294
0.79559707642
0.54109108448
0.74130618572
0.47579109669
0.60206401348
0.69367718697
0.16058707237
0.63788104057

FreeBSD PHP 4.3.0 (2-й результат)
Калибровка поправки 0.19292509556
0.10430693626
0.20098185539
0.4458129406
0.17767786979
0.06940495968
0.38108491897
0.43249595165
0.93939590454
0.86519384384
0.90467691421
0.95204889774
0.26650583744
0.60249495506
--------------------------------
отсюда вывод №1 - в 4.3.0 что-то изменилось :)
№2 - PHP под винду - сакс ;)))
 

ONK

Пассивист PHPСluba
Автор оригинала: Crazy
Тебе просто не попадались криво написанные regexp'ы. :) Некотопые шедевры делают несущественным время исполнения запроса... :)
Мне всё попадалось.

Я помню ходил в магазин, пока исполнялся запрос к базе данных по поиску в индексированных столбцах.
В таблице было 8м записями.... Всего-то, забыл экранировать "_" в середине искомого слова и отправил это дело в LIKE '' . :) Всёравно пришлось в конце концов останавливать Мускул. Слава богу обошлось.
 

ONK

Пассивист PHPСluba
Автор оригинала: ForJest
--------------------------------
отсюда вывод №1 - в 4.3.0 что-то изменилось :)
№2 - PHP под винду - сакс ;)))
Да, похоже они изменили алгоритм поиска именно так как я предположил что будет оптимальнее.


Неет вижу что они сделали,, в последней строке мало пролбелов и много разлчных знаков. Они прсто отказались от разделения строки на фрагменты по знакам, оставили видимо по пробелаи и по одиночнй кавычке для мускула ' ...

Показателен третий снизу тест, там только пробелы были, он совпадает с моим :)..... Вот что значит измерить чистое время -:)
 

ONK

Пассивист PHPСluba
Автор оригинала: ForJest
№2 - PHP под винду - сакс ;)))
Помоему в данном случае второй вывод не очевиден. мои тесты (W2k) почти полность совпадают с приведённым тобой тестом №1
 

ForJest

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