SCRIPT.com.ua
Логин: Пароль:
Регистрация Забыл пароль
МАТЕРИАЛЫ
Поиск
Новости
Материалы
Работа с WDDX в РНР [PHP]
Рецепт по установке web-сервера под Windows [PHP]
Инициализация для Flash Player 8 Beta [Flash]
Криптование [Action Script]
Настрока Homesite под Action Script [Action Script]
Учитесь писать код правильно [PHP]
Пасхальные яйца. [Action Script]
Flash-игры: проще, если знаешь как [Flash]
Установка Ming под win32 Apache+PHP [Action Script]
Wysiwyg HTML Редакторы [DHTML]
Исходники
"Объект" на JavaScript - аналог AsBroadcaster [DHTML]
Запрет кэширования [HTML]
Полупрозрачные картинки, которые 'востанавливаются' при наведении. [DHTML]
Новостная лента v1.2.1 [PHP]
Обход XML-дерева [Action Script]
CDATA и комментарии [XSL]
Кроссразмерный полноэкранный режим [Action Script]
KeyListener [Action Script]
Редирект [HTML]
Текстовый узел [XSL]
Лаборатория
Документация
Файлы
Ссылки
Пользователи
Контакты
Наш выбор
FIFA 06 Platinum Sony PSP
Наши партнеры
Четверг, 28 Октября, 2004
Учитесь писать код правильно [PHP]

Эти тесты делал не я, но чего-то думаю что так оно и есть!


Выносите $переменные из "текстовых строк" - ускорение 25-40%

Одна и таже операция присваивания (либо echo/print для вывода на экран) в зависимости от того, заключены ли переменные в кавычеки или нет, сильно влияет на скорость. В первом и втором вариантах добавлены пробелы, чтобы выравнять размер общего кода для парсинга.

1.      {$x="test".$test;    }

2.      {$x="test $test";    }

3.      {$x="test";$x.=$test;}

Переменная $test содержит строку "1234567890".

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

3.5911

3.5911

00.0%

70.9%







test N2

1

5.0616

5.0616

40.9%

100.0%







test N3

1

4.9870

4.9870

38.9%

98.5%







Итак, никогда не пишите $a="$b", ибо это затормозит программу (в этой строке) на 40%.

Однако, если у вас большая строка, где много текста и переменных, различия в скорости уменьшаются, т.к. общие затраты на парсинг становятся намного больше, чем разные по эффективности команды. Но почему бы и не увеличить скорость программы (строк присваивания) почти на четверть таким простым методом?

1.      {$x="test ".$test." test ".$test." test ".$test;                }

2.      {$x="test $test test $test test $test";                         }

3.      {$x="test ";$x.=$test;$x="test ";$x.=$test;$x="test ";$x.=$test;}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

7.6894

7.6894

00.0%

66.0%







test N2

1

9.5515

9.5515

24.2%

82.0%







test N3

1

11.6506

11.6506

51.5%

100.0%








Короткие переменные не более 7 символов - ускорение 15%

Как влияет длина имен переменных на скорость программы? Если использовать очень длинные переменные - очевидно, что весьма сильно. Однако и с короткими именеми не все просто:

1.      {$x=1;}

2.      {$x2=1;}

3.      {$x03=1;}

4.      {$x004=1;}

5.      {$x0005=1;}

6.      {$x00006=1;}

7.      {$x000007=1;}

8.      {$x0000008=1;}

9.      {$x000000010=1;}

10.  {$x00000000012=1;}

11.  {$x0000000000014=1;}

12.  {$x000000000000016=1;}

13.  {$x0000000000000000000000000000032=1;}

выдает предсказуемый результат:

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

1.7000

1.7000

00.0%

68.5%







test N2

1

1.7028

1.7028

00.2%

68.6%







test N3

1

1.7182

1.7182

01.1%

69.2%







test N4

1

1.7228

1.7228

01.3%

69.4%







test N5

1

1.7536

1.7536

03.2%

70.6%







test N6

1

1.7504

1.7504

03.0%

70.5%







test N7

1

1.7799

1.7799

04.7%

71.7%







test N8

1

1.9604

1.9604

15.3%

78.9%







test N9

1

1.9865

1.9865

16.9%

80.0%







test N10

1

2.0119

2.0119

18.3%

81.0%







test N11

1

2.0302

2.0302

19.4%

81.7%







test N12

1

2.1288

2.1288

25.2%

85.7%







test N13

1

2.4835

2.4835

46.1%

100.0%







Переменные от 32 символов могут тормознуть программу почти на половину.

Но если заполнять пробелами (" "), чтобы все строки "$x=1; ..." по длине занимали одно и тоже расстояние, то получается вот что:

1.      {$x=1;                                   }

2.      {$x2=1;                                  }

3.      {$x03=1;                                 }

4.      {$x004=1;                                }

5.      {$x0005=1;                               }

6.      {$x00006=1;                              }

7.      {$x000007=1;                             }

8.      {$x0000008=1;                            }

9.      {$x000000010=1;                          }

10.  {$x00000000012=1;                        }

11.  {$x0000000000014=1;                      }

12.  {$x000000000000016=1;                    }

13.  {$x0000000000000000000000000000032=1;    }

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

2.1167

2.1167

01.9%

83.3%







test N2

1

2.0766

2.0766

00.0%

81.7%







test N3

1

2.0937

2.0937

00.8%

82.4%







test N4

1

2.0821

2.0821

00.3%

81.9%







test N5

1

2.1145

2.1145

01.8%

83.2%







test N6

1

2.0921

2.0921

00.7%

82.3%







test N7

1

2.1076

2.1076

01.5%

82.9%







test N8

1

2.3058

2.3058

11.0%

90.7%







test N9

1

2.3046

2.3046

11.0%

90.7%







test N10

1

2.3107

2.3107

11.3%

90.9%







test N11

1

2.3111

2.3111

11.3%

90.9%







test N12

1

2.3680

2.3680

14.0%

93.2%







test N13

1

2.5418

2.5418

22.4%

100.0%







Уж как комментировать тест переменной из одного символа (на 2% медленне самого быстрого) - не знаю... Наверно, тесты имеют большую погрешность. Предлагаю кому-нибудь запустить тест на час (исходники теста внизу страницы).

Одно ясно - при длине переменных в 8 и более символов происходит резкое снижение производительности, до 15%! А команд, включающих названия переменных, очень много. Еще один менее резкий скачек на переменных с именем 16 символов в длину и более. А в остальных случаях - чем больше, тем дольше, весьма линейная зависимость.

Вывод - не используйте переменны из 8 и более символов, выиграете 15% скорости (вернее, сэкономите).


Тормозят ли массивы в PHP? Вернее, как именно. Ускорение 40%.

А вот и не тормозят. Я где-то читал, якобы ассоциативные массивы в PHP жутко тормозят. Конечно, тест простой, но большой разницы между непрерывным простым (1), простым (2) и ассоциативным (3) массивами нет (элемент 0000 преобразуется в 0 - это же число, а не строка). И уж явно не тормозят "не ассоциативные не сплошные массивы".

1.      {$test[0000]=1;$test[0001]=1;$test[0002]=1;$test[0003]=1;$test[0004]=1;     }

2.      {$test[1000]=1;$test[1001]=1;$test[1002]=1;$test[1003]=1;$test[1004]=1;     }

3.      {$test["aa"]=1;$test["bb"]=1;$test["cc"]=1;$test["dd"]=1;$test["ee"]=1;     }

4.      {$test[aa]=1;  $test[bb]=1;  $test[cc]=1;  $test[dd]=1;  $test[ee]=1;       }

5.      {$test[0][0]=1;$test[0][1]=1;$test[0][2]=1;$test[0][3]=1;$test[0][4]=1;     }

6.      {$test[2][1]=1;$test[3][8]=1;$test[4][9]=1;$test[33][99]=1;$test[123][99]=1;}

7.      {$test[a][b]=1;$test[x][y]=1;$test[d][c]=1;$test[a][s]=1;$test[b][n]=1;     }

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

5.3924

5.3924

01.1%

28.0%







test N2

1

5.3332

5.3332

00.0%

27.7%







test N3

1

5.7651

5.7651

08.1%

29.9%







test N4

1

7.6543

7.6543

43.5%

39.7%







test N5

1

6.6649

6.6649

25.0%

34.6%







test N6

1

6.6221

6.6221

24.2%

34.3%







test N7

1

19.2820

19.2820

261.5%

100.0%







Что тут можно комментировать.. все очевидно. Доступ к элементу одномерного ассоциативного массива по имени, не заключенному в кавычки, тормозит процесс на треть (относительно того же примера, но в кавычках). А вот в двухмерном массиве программа работает медленне аж в 2.5 раза! После такого теста хочешь не хочешь, а в любой программе пожертвуешь удобством - обращение к элементам массива по имени без кавычек.


Выносите многомерные массивы из "текстовых строк" - ускорение 25-30%. Одномерные можно не выносить.

При использовании многомерных массивов в строках наблюдается заметное снижение скорости Из-за многомерности нужно заключать переменные в парные фигурные скобки.

1.      {$x="test ".$myarray["name"]["second"][1]." test";       }

2.      {$x="test {$myarray[name][second][1]} test";             }

3.      {$x="test ";$x.=$myarray["name"]["second"][1];$x=" test";}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

3.5369

3.5369

00.0%

69.9%







test N2

1

5.0605

5.0605

43.1%

100.0%







test N3

1

4.6017

4.6017

30.1%

90.9%







Тот же пример с ассоциативным 3-х мерным массивом, но с обращением к элементу по его индексному номеру:

1.      {$x="test ".$myarray[3][2][0]." test";       }

2.      {$x="test {$myarray[3][2][0]} test";         }

3.      {$x="test ";$x.=$myarray[3][2][0];$x=" test";}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

3.3012

3.3012

00.0%

73.1%







test N2

1

4.1667

4.1667

26.2%

92.3%







test N3

1

4.5145

4.5145

36.8%

100.0%







Разница в 1 и 2 вариантах очень мала. Это говорит, что потери на не эффективное использование кавычек не слишком большое, чем доступ к массивам (см. тесты в первой главе).

1.      {$x="test".$myarray["test"]."test";}

2.      {$x="test$myarray[test]test";      }

3.      {$x="test{$myarray[test]}test";    }

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

2.8495

2.8495

00.0%

80.9%







test N2

1

2.9519

2.9519

03.6%

83.9%







test N3

1

3.5202

3.5202

23.5%

100.0%







А теперь, на основании всех трех тестов, однозначный вывод: использовать фигурные скобки для обозначения границ имени элемента многомерного массива НЕЛЬЗЯ. Это сильно снижает скорость работы - 25-30% (в третьем варианте от простого добавления скобок скорость понизилась на четверть). Не использовать скобки нельзя. Следовательно, единственный способ не терять 30% скорости - выносить многомерные массивы из скобок.

Такой же тест, но для одномерных:

1.      {$x="test".$myarray["test"]."test".$myarray["test"]."test".$myarray["test"];   }

2.      {$x="test$myarray[test]testtest$myarray[test]testtest$myarray[test]test";      }

3.      {$x="test{$myarray[test]}testtest{$myarray[test]}testtest{$myarray[test]}test";}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

6.5843

6.5843

00.0%

78.0%







test N2

1

6.7770

6.7770

02.9%

80.3%







test N3

1

8.4406

8.4406

28.2%

100.0%







Сравнивая два последних теста очевидно, что одномерные массивы можно и не выносить, потери всего 3-4% ( а вот на простых переменных - потери 25-40%!).


Регулярные выражения: PHP(POSIX) vs Perl.

PHP поддерживает регулярные выражения стандарта POSIX/eger*/ и PERL/preg*/-ориентированные (об их различии тут - php.spb.ru/regular_expression.html). Кто из них работает быстрее?

Хочу заранее предупредить любителей Перла, чтобы не радовались: хоть перловые реги и круче пхпышных, только ничто и никто не мешает использовать в PHP перловые реги! Наверно, потому их и встроили в PHP, что уж больно тормоза большие... :-)

Итак, простейший текст. Поиск простого выражения в тексте, который состоит из многократного повторения данной статьи (получается размер переменной $text в 3 Мб).

Тест вызывает всего 1 раз, ибо реги имеют встроенное средство для кеширования результатов компиляции. Т.е. перед запуском проиходит компиляции, а повторные реги не компилируются. Это особенности регулярных выражений. Разные языки программирования в состоянии хранить разное число откомпилированных выражений, что вызывались (в порядке вызова в программе). И в данном тесте как раз нет эффекта от компиляции, т.к. функция вызывается всего один раз.

1.      {eregi("МаС+иВ",$text);}

2.      {preg_match("/МаС+иВ/im",$text);}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

1.3339

1.3339

107.8%

100.0%







test N2

1

0.6417

0.6417

00.0%

48.1%







1.      {eregi("(ма[a-zа-я]{1,20})",$text);}

2.      {preg_match("/(ма[a-zа-я]{1,20})/im",$text);}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

0.4521

0.4521

76.9%

100.0%







test N2

1

0.2556

0.2556

00.0%

56.5%







Пример для другого выражения и 30-мегабайтного текста (все те же повторы статьи, что вы сейчас читаете):

1.      {eregi("(ма[a-zа-я]{1,20})",$text);}

2.      {preg_match("/(ма[a-zа-я]{1,20})/im",$text);}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

1.3430

1.3430

60.6%

100.0%







test N2

1

0.8365

0.8365

00.0%

62.3%







Я еще писал штук пять разных выражений, но тенденция не меняется. Скорость может меняться, но Pelr обгоняет POSIX минимум на половину. Этого достаточно, чтобы похоронить функции регулярных выражений от PHP (POSIX). Для всех функций есть аналогичные Perl-ориентированные (все они встроены в PHP).

Далее один очень показательный пример на этой же статье (увеличение до 28Мб). Пример ищет в тексте e-mail. По свойству "жадности" регулярных выражений будет найден самый большой и наболее близкий к левому краю адрес.

Этот пример огорчит любителей перла. Приятно их огорчать :-)

1.      {eregi("([a-z_-]+@([a-z][a-z-]*\.)+([a-z]{2}|com|mil|org|net|gov|edu|arpa|info|biz))",$text);}

2.      {preg_match("/([a-z_-]+@([a-z][a-z-]*\.)+([a-z]{2}|com|mil|org|net|gov|edu|arpa|info|biz))/im",$text);}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

11.6828

11.6828

680.3%

100.0%







test N2

1

1.4973

1.4973

00.0%

12.8%







Из одного теста делать вывод сложно, но, видимо, чем сложнее регулярное выражение, тем больше POSIX отстает от Perl.

А теперь тот же пример, но только в статье (увеличение до 28Мб) нет НИ ОДНОГО символа "@" (я специально сделал копию статьи и стер эти символы):

1.      {eregi("([a-z_-]+@([a-z][a-z-]*\.)+([a-z]{2}|com|mil|org|net|gov|edu|arpa|info|biz))",$text,$ok); echo $ok[1];}

2.      {preg_match("/([a-z_-]+@([a-z][a-z-]*\.)+([a-z]{2}|com|mil|org|net|gov|edu|arpa|info|biz))/im",$text,$ok); echo $ok[1];}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

0.5854

0.5854

00.0%

10.2%







test N2

1

5.7671

5.7671

885.2%

100.0%







Что мы видим?.. Ничто в этом мире не совершенно. Конечно, это очень не оптимизированное выражение для поиска email'ов, но всё же все те, кто кричал мне в форуме "ereg - отстой", на этом и похожих примерах могут отдыхать. Бывает же, что в тексте нет ни одной собачки :-)

Итак, вывод о скорости с примерами был дан выше. Вывод однозначный - надо использовать Perl-ориентированные регулярные выражения. В начеле главы я упоминал о кешировании откомпилированных копий регов. Если в программе одно и тоже выражение встречается неоднократно, производительность может отличаться не просто многократно, а в 10-100-1000 раз!

Селдующий пример вызывается 200 раз подряд над текстом в 250Кб:

1.      {eregi("МаС+иВ",$text);}

2.      {preg_match("/МаС+иВ/im",$text);}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

17.6384

17.6384

72381.4%

100.0%







test N2

1

0.0243

0.0243

00.0%

00.1%







Что такое кеш - знают все. Видимо именно с кешем в PHP проблеммы... Кстати, ради примера, отключите в BIOSе вашего комптьютера кеш процессора и попробуйте загрузить Windows 2000... Не дождетесь! (Кажется, их называют L1 и L2 - два разных кеша для кода и данных первого и второго уровня, какой то из них можно отключить.)


Циклы: for, foreach, while, count/sizeof() - ускорение 15%-30%

В начале программы создается массив $test из целых чисел (100 000 элементов). Потом один раз запускаются приведенные ниже примеры. Цикл проходит данный массив 3-мя способами (разными циклами) и выполняет кое-какие операции. Не выполнять в цикле ничего нельзя, ибо это будет уже совсем не реальный тест.

1.      {$x=0; foreach($test as $n)                          { $x=sprintf("test%08i",$i);        }}

2.      {$x=0; for ($it=0; $it<100000; $it++)                { $x=sprintf("test%08i",$i);        }}

3.      {$x=0; $it=0; while($it<100000)                      { $x=sprintf("test%08i",$i); $it++; }}

4.      {$x=0; for ($it=0; $it<count($test); $it++)          { $x=sprintf("test%08i",$i);        }}

5.      {$x=0; $it=0; while($it<count($test))                { $x=sprintf("test%08i",$i); $it++; }}

6.      {$x=0; $co=count($test); for ($it=0; $it<$co; $it++) { $x=sprintf("test%08i",$i);        }}

7.      {$x=0; $co=count($test); $it=0; while($it<$co)       { $x=sprintf("test%08i",$i); $it++; }}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

12.0313

12.0313

154.4%

100.0%







test N2

1

4.7290

4.7290

00.0%

39.3%







test N3

1

4.7712

4.7712

00.9%

39.7%







test N4

1

10.2847

10.2847

117.5%

85.5%







test N5

1

10.3466

10.3466

118.8%

86.0%







test N6

1

9.1271

9.1271

93.0%

75.9%







test N7

1

9.1409

9.1409

93.3%

76.0%







Почему sprintf, а не реальное echo? echo использовать нельзя, т.к. от него будет немерянный буфер (OUTPUT в браузер или консоль).

Теперь о деле. Бесспорный вывод - использование foreach сильно тормозит дело, а между for и while большой разницы нет. (На голом тесте for/while/foreach {..} тормоза foreach - 30%). Это не удивительно, т.к. foreach делает копию массива, на что тратиться масса времени (хотя это только слухи).

Вывод с count() не столь очевиден, потому что от разного текста в цикле % тормознутости от самого быстрого варианта резко возрастает... Я взял цикл с небольшой нагрузкой - проход по огромному массиву $test + форматирование функцией sprintf. Как видите, варинты с count() и заменяющей эту функцию перемнной $co различаются на 10% по скорости между собой (не смотрите на варинант с константой в 100000, заранее знать кол-во элементов невозможно).

Вывод о не ассоциативных массивах: 1) foreach существенно замедляет работу 2) использование count() в простых циклах - замедленение 10%. Но на сложных циклах потери от лишних запусков count() будут абсолютно незаметны, так что ситуация не очевидна.

Сравнение count() и sizeof().

Судя по мануалу - это алиасы. Об этом написано на страницах самих функций и дополнительной странице "Appendex => Aliases list". Что же мы видим на массиве в 100000 элементов:

1.      {$x=0; for ($it=0; $it<count($test); $it++)  { $x=sprintf("test%08i",$test[$it]);}}

2.      {$x=0; for ($it=0; $it<sizeof($test); $it++) { $x=sprintf("test%08i",$test[$it]);}}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

3.0087

3.0087

15.7%

100.0%







test N2

1

2.5998

2.5998

00.0%

86.4%







Пусть тесты будут иметь погрешности... Но результат один - count() заметно отстает по скорости от sizeof()! Хм, я бы к записи в мануале сделал приписку: "The sizeof() function is an alias for count(), but последний сильно тормозит!"

Если кол-во элементов в массиве меньше 65000 (64К), то эти функции по скорости практически не различимы. Тут вывод простой - переходим на использование sizeof(), как ускоренного алиаса count(). Это принесет свои результаты на огромных массивах.

Ассоциативные массивы: тестирование разных способов перебора

С ними наблюдается таже проблема: на разных по величине массивах разные функции эффективны, но лучше всех foreach!

Массив в 200 элементов и 1000 повторов программы:

1.      {$x=0; foreach($test as $k=>$v) { $x=sprintf("%s=>%s\n",$k,$v);                                                           }}

2.      {$x=0; reset($test); while (list($k, $v) = each($test)) { $x=sprintf("%s=>%s\n",$k,$v);                                   }}

3.      {$x=0; $k=array_keys($test); $co=sizeof($k); for ($it=0; $it<$co; $it++) { $x=sprintf("%s=>%s\n",$k[$it],$test[$k[$it]]); }}

4.      {$x=0; reset($test); while ($k=key($test)) { $x=sprintf("%s=>%s\n",$k,current($test)); next($test);                       }}

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

8.1222

8.1222

00.0%

78.7%







test N2

1

10.3221

10.3221

27.1%

100.0%







test N3

1

9.7921

9.7921

20.6%

94.9%







test N4

1

8.9711

8.9711

10.5%

86.9%







Тоже самое, но массив в 5000 элементов и 200 повторов:

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

14.4473

14.4473

00.0%

67.2%







test N2

1

18.6801

18.6801

29.3%

86.9%







test N3

1

21.5056

21.5056

48.9%

100.0%







test N4

1

15.8514

15.8514

09.7%

73.7%







Опять тоже самое, но массив в 100 000 элементов и без повторов:

счетчик

кол-во
вызовов

общее
вpемя

сpеднее
вpемя

% от min

% от max

общее
время

test N1

1

3.5116

3.5116

00.0%

82.8%







test N2

1

3.9724

3.9724

13.1%

93.6%







test N3

1

4.2436

4.2436

20.8%

100.0%







test N4

1

4.0026

4.0026

14.0%

94.3%







Другие тесты на холостых циклах тоже показывают преимущество foreach.

Резюме:

  • sizeof() лучше, чем count()
  • в циклах sizeof лучше вообще заменить на переменную
  • for и while практически не отличимы
  • для перебора простых индексных массивов нужно использовать for или while
  • для перебора ассоциативных массивов нужно использотьва foreach

Для чтения файла file() быстрее, чем fopen+цикл - ускорение 40%

Чтобы прочитать в массив $x файл размером 1Мб (100 000 строк по 10 байт) можно воспользоваться двумя вариантами: чтение файла с помощью file(), либо традиционным методом fopen/fgets. Разумеется, для файлов разного объема и содержимого скорость может меняться. Но в данном примере статистика такова: file("1Mb_file.txt") работает на 40% быстрее, чем:

 
   $f=fopen("1Mb_file.txt","r") or die(1);
   while($x[]=fgets($f,1000));
   fclose($f);
Аналогичные варианты

 
   $f=fopen("1Mb_file.txt","r") or die(1);
   while($s=fgets($f,1000)) $x[]=$s;
   fclose($f);

или

 
   $f=fopen("1Mb_file.txt","r") or die(1);
   while(!feof($f))) $x[]=fgets($f,1000);
   fclose($f);
работают еще медленнее (во втором случае лишняя функция feof() заметно снижает скорость). Тот же тест, но на 15Мб файле (100 000 строк по 150 байт) показывает разницу в 50%, в пользу file(). Тест проводился так, чтобы исключить фоновый своппинг во время работы из-за предшествующих команд создания/чтения таких больших файлов. Подсчитать тоже самое на очень маленьких файлах в 1-2 Кб не представляется возможным, т.к. операцию чтения нельзя повторять в течении одного теста, операции чтения будут кешироваться...

 

© Дмитрий Бородин
php.spb.ru


Опубликовал: Boyan (18:43) | комментарии [0]
< назад
Вверх © Copyright 2004-2014 Script.com.ua



Версия для печати