[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Тест скорости работы некоторых функций и браузеров
CaypoH
Спор в этой теме, по поводу скорости работы функций mysql_fetch_array и mysql_fetch_row побудил меня провести несколько тестов, чтобы наглядно увидеть имеют ли таковые право на почву для произрастания, или же всё это лишь слухи и домыслы. А так же чтобы подстегнуть свою паранойю по поводу быстродействия и бесконечных оптимизаций.

Тесты проводились на компьютере следующие конфигурации:
Процессор: Intel Pentium 4 521, Socket 775, 90nm, степпинг 1, ревизия ядра E0, на скорости 2800 Mhz. Температура процессора во время проведения тестов составляла ~39 градусов цельсия, отсутствие тротлинга наблюдалось программой S&M.
Оперативная память: DDR2-800 Hynix с задержками 6-6-6-18 @ 400 Mhz, 2 планки по 1024, работающие в dual-channel.
Операционная система: Windows 7, 32 бита.
Браузеры: Mozilla FireFox 3.5.5, Google Chrome 3.0.195.33, Internet Explorer 8.

файл test.php, который собственно и запускался в различных браузерах:
test.php
<?
$connect = mysql_connect('localhost', 'root', '');
$selectdb = mysql_select_db('tests', $connect);

$first_name = md5(rand() + microtime(1));
$last_name = md5(rand() - microtime(1));
$age = rand(1,100);

$start_time = microtime(1);

for ($i=0; $i<10000; $i++)
{
mysql_query("INSERT INTO `test` VALUES ('', '".$first_name."', '".$last_name."','".$age."')");
}
$stop_time = microtime(1);
$time = $stop_time - $start_time;
print "Время выполнения: ".$time;
?>

База данных:
CREATE TABLE `test` (
`id` INT NOT NULL AUTO_INCREMENT ,
`first_name` TEXT NOT NULL ,
`last_name` TEXT NOT NULL ,
`age` INT NOT NULL ,
PRIMARY KEY ( `id` )
)
TYPE = MYISAM ;

Итак, мы видим что производилась запись 10 тысяч строчек со случайными данными в базу данных. Для каждого браузера было выполнено по 5 таких записей, после каждой записи внесенный в таблицу данные удалялись, так что новая запись всегда производилась в пустую таблицу.

Результаты.

FireFox:
Свернутый текст
Время выполнения: 3.6861269474
Время выполнения: 3.61330199242
Время выполнения: 3.60497283936
Время выполнения: 3.44344711304
Время выполнения: 3.59117603302

Среднее время выполнения запроса в браузере FireFox: 3.587804985048


Chrome:
Свернутый текст
Время выполнения: 3.69179391861
Время выполнения: 3.5473549366
Время выполнения: 3.64253497124
Время выполнения: 3.6500980854
Время выполнения: 3.68023014069

Среднее время выполнения запроса в браузере Google Chrome: 3.642402410508


IE8:
Свернутый текст
Время выполнения: 3.61438894272
Время выполнения: 3.52051591873
Время выполнения: 3.71573400497
Время выполнения: 3.73547005653
Время выполнения: 3.57179808617

Среднее время выполнения запроса в браузере Internet Explorer 8: 3.631581401824

Тут, прежде чем подвести промежуточные итоги, хочу заметить что изначально определение переменных делалось внутри цикла, дабы заносить в базу различную информацию, что естественно занимало больше времени. Вот итоговые результаты по всем браузерам, когда присваивание значений переменным проводилось внутри цикла:

Среднее время выполнения запроса в браузере FireFox: 4.269325399398
Среднее время выполнения запроса в браузере Google Chrome: 4.437961959838
Среднее время выполнения запроса в браузере Internet Explorer 8: 4.28515238762

Итак, что мы видим. Быстрее всех сработал FireFox, на втором месте ie8, и в аутсайдерах оказался chrome. Причем, как видно, такая ситуация в обоих вариантах теста, что позволяет с уверенностью говорить о закономерности зависимости результатов от используемого браузера. Пусть даже эти значения разнятся десятыми либо сотыми долями секунды.


Чтож, данные, с которыми мы будем работать для проверки функций mysql_fetch_array и mysql_fetch_row в базе есть (после последнего занесения я их не удалял). Теперь нам понадобится немного изменить файл test.php. А именно:
test.php

<?
$connect = mysql_connect('localhost', 'root', '');
$selectdb = mysql_select_db('tests', $connect);

$start_time = microtime(1);
$i=0;

$sql = mysql_query("SELECT * FROM `test`");
while($array = mysql_fetch_array($sql)) $i++;

$stop_time = microtime(1);
$time = $stop_time - $start_time;
print $i."<br>";
print "Время выполнения: ".$time;
?>

Переменная $i заодно не даст обсчитаться, и покажет что было обработано именно 10 тысяч строчек из базы. Конечно, на её увеличение на единицу в каждом проходе цикла тоже будет тратиться время, но все функции, так же как и все браузеры, окажутся в одинаковых условиях, ибо изменять мы будем только имена функций. Этот тест будем проводить по 10 раз для каждой функции, и так же вычислим среднее время выполнения.

Первым в бой идёт функция mysql_fetch_array
Ну что, всё готово, тогда на старт, внимание, марш!
И вот они результаты.
Firefox
Свернутый текст
Время выполнения: 0.0947389602661
Время выполнения: 0.0930860042572
Время выполнения: 0.0925710201263
Время выполнения: 0.0962450504303
Время выполнения: 0.0988190174103
Время выполнения: 0.0994658470154
Время выполнения: 0.109087944031
Время выполнения: 0.0958249568939
Время выполнения: 0.0974459648132
Время выполнения: 0.0921769142151

Среднее время выполнения запроса в браузере FireFox: 0.0969461679459


Chrome
Свернутый текст
Время выполнения: 0.0818691253662
Время выполнения: 0.0803220272064
Время выполнения: 0.0852499008179
Время выполнения: 0.0840809345245
Время выполнения: 0.0818247795105
Время выполнения: 0.0949058532715
Время выполнения: 0.0831689834595
Время выполнения: 0.0854468345642
Время выполнения: 0.0829141139984
Время выполнения: 0.0838310718536

Среднее время выполнения запроса в браузере Google Chrome: 0.084557557106


IE8
Свернутый текст
Время выполнения: 0.0910029411316
Время выполнения: 0.0793159008026
Время выполнения: 0.0997400283813
Время выполнения: 0.0942821502686
Время выполнения: 0.0860710144043
Время выполнения: 0.083781003952
Время выполнения: 0.0885879993439
Время выполнения: 0.086168050766
Время выполнения: 0.0810101032257
Время выполнения: 0.0820741653442

Среднее время выполнения запроса в браузере Internet Explorer 8: 0.087203335762

А вот здесь уже Chrome вышел победителем. IE снова на втором месте, а FireFox переместился на последнее.

Теперь время заменить функцию mysql_fetch_array на mysql_fetch_row, вы ведь не забыли что именно для измерения разницы в их скорости работы мы всё это и зетяли?
Второй участник, на старт!
И вот результаты:
FireFox
Свернутый текст
Время выполнения: 0.086287021637
Время выполнения: 0.0744988918304
Время выполнения: 0.0833699703217
Время выполнения: 0.0903041362762
Время выполнения: 0.0823390483856
Время выполнения: 0.0984809398651
Время выполнения: 0.115894079208
Время выполнения: 0.0857601165771
Время выполнения: 0.0977430343628
Время выполнения: 0.0858080387115

Среднее время выполнения запроса в браузере FireFox: 0.0900485277175


Chrome
Свернутый текст
Время выполнения: 0.0715789794922
Время выполнения: 0.0716831684113
Время выполнения: 0.0780971050262
Время выполнения: 0.0751450061798
Время выполнения: 0.0778539180756
Время выполнения: 0.075963973999
Время выполнения: 0.10294508934
Время выполнения: 0.0760939121246
Время выполнения: 0.0724189281464
Время выполнения: 0.0699789524078

Среднее время выполнения запроса в браузере Google Chrome: 0.0771759033203


IE8
Свернутый текст
Время выполнения: 0.0722630023956
Время выполнения: 0.0761079788208
Время выполнения: 0.0794448852539
Время выполнения: 0.0832159519196
Время выполнения: 0.0795829296112
Время выполнения: 0.080137014389
Время выполнения: 0.0826289653778
Время выполнения: 0.0789940357208
Время выполнения: 0.101473808289
Время выполнения: 0.0789241790771

Среднее время выполнения запроса в браузере Internet Explorer 8: 0.0812772750855

Подведём промежуточный итог: по скорости выполнения браузеры остались на своих местах: Chrome, IE8, FireFox.

Ну и раз уж пошла такая пьянка, я решил протестировать и функцию mysql_fetch_assoc.
И вот результаты.
FireFox
Свернутый текст
Время выполнения: 0.0927081108093
Время выполнения: 0.0921890735626
Время выполнения: 0.134669065475
Время выполнения: 0.0911610126495
Время выполнения: 0.0893049240112
Время выполнения: 0.092465877533
Время выполнения: 0.101039171219
Время выполнения: 0.0869798660278
Время выполнения: 0.0932190418243
Время выполнения: 0.108642101288

Среднее время выполнения запроса в браузере FireFox: 0.09823782444


Chrome
Свернутый текст
Время выполнения: 0.0751860141754
Время выполнения: 0.0822050571442
Время выполнения: 0.081876039505
Время выполнения: 0.0802240371704
Время выполнения: 0.0795259475708
Время выполнения: 0.0783250331879
Время выполнения: 0.0789539813995
Время выполнения: 0.0811378955841
Время выполнения: 0.0771028995514
Время выполнения: 0.0806109905243

Среднее время выполнения запроса в браузере Google Chrome: 0.0795147895813


IE8
Свернутый текст
Время выполнения: 0.0873830318451
Время выполнения: 0.0751569271088
Время выполнения: 0.0797109603882
Время выполнения: 0.0844130516052
Время выполнения: 0.0836281776428
Время выполнения: 0.0853228569031
Время выполнения: 0.0884130001068
Время выполнения: 0.0873761177063
Время выполнения: 0.0994210243225
Время выполнения: 0.078458070755

Среднее время выполнения запроса в браузере Internet Explorer 8: 0.0849283218384

И снова ничего не изменилось. Быстрее всех Chrome, на втором месте IE8, аутсайдер FireFox.
Из всех этих тестов можно сказать вот что - Chrome быстрее всех обрабатывает запросы на извлечение информации из БД, однако находится позади остальных при обработке запросов добавления информации в БД. IE же крепкий середняк и там, и там.
Но теперь пора бы перейти и определению функции лидера.
Под FireFox на первом месте функция mysql_fetch_row (0.0900485277175), на втором mysql_fetch_array (0.0969461679459) и позади всех mysql_fetch_assoc (0.09823782444)

Под Chrome лидер снова mysql_fetch_row (0.0771759033203), чуть медленнее mysql_fetch_assoc (0.0795147895813) и медленнее всех mysql_fetch_array (0.084557557106)

Ну и под IE8 в шустрее всех снова mysql_fetch_row, далее mysql_fetch_assoc ну и самая медленная снова mysql_fetch_array

Как последний штрих осталось, разве что, вычислить среднее время выполнения каждой функции, и сравнить их. Итак:
mysql_fetch_array: 0.0969461679459 в фаерфоксе + 0.084557557106 в хроме и + 0.087203335762 в эксплорере, итого 0.2687070608139. Делим это значение на 3 и получаем 0.0895690202713
mysql_fetch_row: серднее арифметическое 0.0828339020411
mysql_fetch_assoc: среднее время 0.0875603119532
Т.е. в абсолюте шустрее всех выполняется функция mysql_fetch_row.


Выводы:
Да, mysql_fetch_row() быстрее чем mysql_fetch_array(). Однако на сколько? Несколько тысячных долей секунды! Это при объёме базы данных в 10 тысяч строк. Плюс, нужно учитывать, что все эти тесты проводились на локальной машине, а ведь в обыденной работе нужно учитывать и ширину интернет канала, время отклика и другие связанные с коннектом факторы, которые, по сути, стирают любую разницу в скорости выполнения данных функций. К тому же некую долю случайности в результаты всё же вносят ошибки предсказателя переходов процессора.
Так что использовать функцию row взамен array в погоне за скоростью бессмысленно. К тому же суть в функции не в увеличении скорости работы, а в том, чтобы возвращать несколько другие значения, нежели mysql_fetch_array.
За сим всё, спасибо за внимание.



Спустя 14 минут, 15 секунд (22.11.2009 - 12:54) dr_Lev написал(а):
А при чем тут браузеры? скрипт то выполняется на сервере.

Спустя 38 минут, 58 секунд (22.11.2009 - 13:33) CaypoH написал(а):
ну, видимо разные браузеры по разному обрабатывают те данные, которые им нужно передать на сервер, на котором эти данные, опять же через третьи руки, преобразуются в машинный код который передаётся процессору.
а у тебя какое объяснение разницам во времени выполнения скрипта в разных браузерах?

Спустя 6 часов, 45 минут, 54 секунды (22.11.2009 - 20:19) vagrand написал(а):
ИМХО бред.
При одинаковом сервере, при чем не только его конфигурации но и загруженности на момент выполнения теста браузер может влиятьтолько на скорость формирования запроса и разбора ответа. Даже не на ПОСЫЛКУ запроса и ПОЛУЧЕНИЕ ответа, т.к. за это отвечает канал (если сервер удаленный).
Т.е. при всех одинаковых параметрах кроме браузеров у тебя будет расхождение при тесте любой функции, будь то mysql_fetch_row или echo.

+ насколько я понял сервак у тебя стоит на той-же машине где ты запускал браузеры, т.е. твой тест уже не может быть верным, т.к. 100% каждый из перечисленных браузеров занимает в ОЗУ разное количество байтов, соответственно нагрузка уже разная.

Т.Е, твой тест говорил только о том какой из браузеров сам посебе работает шустрее.

Спустя 1 день, 18 часов, 9 минут, 29 секунд (24.11.2009 - 14:28) twin написал(а):
Обалдеть)))) Круто, очень похвально такое трудолюбие и желание разобраться.
Только:
Причем тут время исполнения скрипта? И даже оно измеренно не корректно...

Основной проблемой mysql_fetch_array() является занимаемая оперативная память. Она возвращает два массива, а значит требует на много больше памяти. Если запрос толстый, то это бывает очень неприятно.

Вот нашел очень грамотное объяснение (не я автор)

Цитата
Есть вызов mysql_fetch_row .
Возвращает строго определенные данные - строку массива результата.
Ключами элементов являются номера столбцов.
Вызов хорош тем, что при строго детерминированном SELECT-запросе (т.е. без звездочек) - также является полным и строго детерминированным.
Количество элементов массива всегда соответствует количеству столбиков запроса.
Неудобен тем, что связь через номер столбика не надежнаяи и наглядная, но такая запись, как

for($res = mysql_query( "SELECT id, name, grp FROM tbl"); 
    list( $id, $name, $grp) = mysql_fetch_row($res); )
  echo "$id/$name/$grp";


этот недостаток практически устраняет.

Есть вызов mysql_fetch_assoc .
Возвращает строго определенные данные - строку массива результата.
Ключами элементов являются имена столбцов.
Вызов хорош тем, что при строго детерминированном SELECT-запросе (т.е. без звездочек и с алиасами, исключающими неоднозначность) - также является полным и строго детерминированным.
Несколько плох тем, что количество элементов массива соответствует количеству столбиков запроса только тогда, когда нет неоднозначности полей. Иначе поля теряются.
При запросе без неоднозначностей - прекрасен жесткой связью имени столбика и ключа массива.
for($res = mysql_query( "SELECT * FROM tbl"); 
    $row = mysql_fetch_row($res); )
    echo $row['id'].'/'.$row['name'].'/'.$row['grp'];


Есть вызов mysql_fetch_array .
Возвращает кашу, несоответствующую никакому осмысленному набору данных, на поверку оказывающуюся помесью результатов первых двух вызовов.
Помимо этого факта сочетает в себе недостатки их обоих.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.