Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: странная разница в скорости
Форумы портала PHP.SU » » Работа с файловой системой и файлами » странная разница в скорости

Страниц (2): [1] 2 »
 

1. LIME - 17 Августа, 2011 - 12:03:02 - перейти к сообщению
вычитал что
PHP:
скопировать код в буфер обмена
  1. $f=fopen('CHANGES.txt','rt');
  2. $lines=explode("\n",fread($f,sizeof('CHANGES.txt')));

быстрее чем 1 ф-ция
при этом еще и конец строки отрубает
решил проверить вот таким тестом
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. $q=time()+microtime();
  3. for ($i=0;$i<10000;$i++) $f=file('CHANGES.txt');
  4. $w=time()+microtime();
  5. echo $w-$q.'<br>';
  6. $q=time()+microtime();
  7. for ($i=0;$i<10000;$i++) {
  8.         $f=fopen('CHANGES.txt','rt');
  9.         $lines=explode("\n",fread($f,sizeof('CHANGES.txt')));
  10. }
  11. $w=time()+microtime();
  12. echo $w-$q;
  13. ?>
результат впечатлил
38.612843036652
2.7759659290314
ерунда какая-то получается
есть комментарии?
(Добавление)
есть смысл проверить на буферизацию?
(Добавление)
дело не в буферизации
наделал 1000 копий файлов
результат тотже
2. EuGen - 17 Августа, 2011 - 12:30:18 - перейти к сообщению
Думаю, понять это не так уж и сложно, если вспомнить о способах переноса строк и о том, как мы с ними работаем в обоих случаях.
Простой пример
Файл test.txt:
CODE (htmlphp):
скопировать код в буфер обмена
  1. user@host:/path$ cat test.txt
  2. 000
  3. 100
  4. 200
  5. 300
  6. 400
  7. 500
  8. 600
  9. 700
  10. 800
  11. 900

Скрипт, которым делается тест:
PHP:
скопировать код в буфер обмена
  1. function benchmark($func, $args, $times)
  2. {
  3.         $max=(int)$times;
  4.         $time_start     = microtime(true);
  5.         $mem_start      = memory_get_usage();
  6.         for($i=0; $i<$max; $i++)
  7.         {
  8.                 call_user_func_array($func, $args);
  9.         }
  10.         $time_end       = microtime(true);
  11.         $mem_end        = memory_get_usage();
  12.         return array(
  13.                 'time'  => $time_end - $time_start,
  14.                 'memory'=> $mem_end  - $mem_start
  15.         );
  16. }
  17.  
  18. var_dump(benchmark(function()
  19.         {
  20.                 $f=fopen('test.txt','rt');
  21.                 $lines=explode("\n",fread($f,sizeof('test.txt')));
  22.         },array(),$_SERVER['argv'][1]));
  23. var_dump(benchmark(function()
  24.         {
  25.                 $f=file('test.txt');
  26.         },array(),$_SERVER['argv'][1]));

Запуск и результат:
CODE (htmlphp):
скопировать код в буфер обмена
  1. user@host:/path$ php bench.php 300000
  2. array(2) {                                      
  3.   ["time"]=>                                    
  4.   float(9.9667201042175)                        
  5.   ["memory"]=>                                  
  6.   int(616)                                      
  7. }                                              
  8. array(2) {                                      
  9.   ["time"]=>                                    
  10.   float(13.309278011322)                        
  11.   ["memory"]=>                                  
  12.   int(192)                                      
  13. }

Хотя даже в этом случае разница не в 15 раз. Еще следует помнить, что t - режим, поддерживающийся только в Windows (он только там имеет смысл), преобразующий \n в \r\n
3. LIME - 17 Августа, 2011 - 12:40:46 - перейти к сообщению
EuGen пишет:
Еще следует помнить, что t - режим, поддерживающийся только в Windows (он только там имеет смысл), преобразующий \n в \r\n
еще в мак
так в этом +
EuGen пишет:
Думаю, понять это не так уж и сложно, если вспомнить о способах переноса строк и о том, как мы с ними работаем в обоих случаях.
не понял
можно подробнее?
почему занимая меньше памяти file работает медленнее?
у меня получилась бОльшая разница
видимо из-за размера файла (117kB)
4. DeepVarvar - 17 Августа, 2011 - 12:42:28 - перейти к сообщению
Таки да.
В случае с file мы начинаем seek'ать файл кусками для получения массива.
А в случае с fopen, открыв, читаем все в память и уже там разбираем - обращения к диску.
Да и для чистоты эксперимента стоит в каждой итерации делать clearstatcache();
5. LIME - 17 Августа, 2011 - 12:48:38 - перейти к сообщению
DeepVarvar пишет:
В случае с file мы начинаем seek'ать файл кусками для получения массива.
в смысле кусочками? )) по символу пока не встретим конец?
это объясняет конечно но это же практически недоработка file...
6. EuGen - 17 Августа, 2011 - 13:07:12 - перейти к сообщению
DeepVarvar пишет:
Да и для чистоты эксперимента стоит в каждой итерации делать clearstatcache();

Зачем? Результаты ни одной из используемых выше функций не кешируются.
В первом случае памяти ушло больше, так как мы еще ресурс оставляли.
7. LIME - 17 Августа, 2011 - 13:11:46 - перейти к сообщению
ну в общем понятно
спасибо
8. PATCH - 18 Августа, 2011 - 08:26:43 - перейти к сообщению
LIME пишет:
не понял
можно подробнее?
почему занимая меньше памяти file работает медленнее?
у меня получилась бОльшая разница
видимо из-за размера файла (117kB)


т.е

PHP:
скопировать код в буфер обмена
  1. $f=fopen('CHANGES.txt','rt');
  2. $lines=explode("\n",fread($f,sizeof('CHANGES.txt')));

этот пример будет быстрее при обработки файла скажем большим весом (допустим мб 8)

чем

PHP:
скопировать код в буфер обмена
  1. $f=file('CHANGES.txt');

я правильно понел?
9. LIME - 18 Августа, 2011 - 13:14:58 - перейти к сообщению
PATCH да
быстрее будет всегда
а чем больше файл тем больше разница в скорости
объясните в чем смысл такой реализации file()
всеравно весь файл в итоге в оперативке окажется
должен же быть смысел ))
10. White - 18 Августа, 2011 - 14:13:02 - перейти к сообщению
LIME пишет:
в итоге в оперативке окажется
только при использовании fopen() и друзей памяти в два раза больше будет использовано. если файл скажем 10МБ, то сначала эти 10МБ отведутся под строку хранящую содержимое файла, а потом еще 10МБ под массив со строками из файла, итого 20Мб.
в случае с file() файл будет считываться по 1байту, и последовательно заполняться массив, итого 10Мб + 1байт
PATCH у fread() есть магическое число 8192
11. LIME - 18 Августа, 2011 - 14:17:23 - перейти к сообщению
White пишет:
итого 20Мб
точно
White пишет:
есть магическое число 8192
это что такое?
12. EuGen - 18 Августа, 2011 - 14:25:11 - перейти к сообщению
Однако не всегда 8192.
Цитата:
if the stream is read buffered and it does not represent a plain file, at most one read of up to a number of bytes equal to the chunk size (usually 8192) is made; depending on the previously buffered data, the size of the returned data may be larger than the chunk size.
13. White - 18 Августа, 2011 - 14:36:04 - перейти к сообщению
EuGen возможно, но зачем рисковать. для таких случаев есть file_get_contents() например.
честно, не доконца уловил суть того, что они пытаются сказать. какие это данные previously buffered,
и о каком вообще потоке идет речь. если не сложно расшифруйте.
14. EuGen - 18 Августа, 2011 - 14:38:33 - перейти к сообщению
О любом, который можно буферизовать. Скажем, поток, который предоставляет ресурс, связанный с локальным файлом - буферизуем, а тот, что указывает на http://что-то - нет. (впрочем, теоретически себе это представить можно, но это зависит от соответствующего wrapper-а )

file_get_contents плоха, когда нужно получать информацию и что-то с ней делать при размерах файла, скажем, > 1Gb
15. White - 18 Августа, 2011 - 14:42:32 - перейти к сообщению
EuGen с первым понятно. насчет инфы > 1Gb даже не знаю, с такими запросами помоему лучше вообще к php не обращаться. а чем в таком случае хуже file_get_contents()?

 

Powered by ExBB FM 1.0 RC1