Witam
Mam taki pytanko, co lepiej wybrać przy dość częstym liczeniu linii z pliku?
Nasuwają mi się te dwie metody:
1.
if($fh = fopen('file', 'r')) {
while($chunk = fread($fh, 8192)) {
$liczba_lini += substr_count($chunk, "\n");
}}
2.
$chunk = @shell_exec('wc -l file');
preg_match("/(.*?) \/home(.?)/",$chunk ,$czesc);
$liczba_lini = $czesc[1];
I teraz nie wiem która jest wydajniejsza, mniej obciążająca serwer pamięć itp
Wydaje mi się ze metoda druga, ale nie wiem jak to z częstym wychodzeniem z php czy to nie spowalnia i nie katuje serwera.
A może ktoś zna jeszcze inna metodę?
Z niecierpliwością czekam na odpowiedz i pozdrawiam
lukaskolista
23.03.2011, 09:18:48
Cytat(lukaskolista @ 23.03.2011, 09:18:48 )

count(file('plik.txt'));
Czy ta metoda czasami nie zabiera najwięcej pamięci? ponieważ tworzy tablice
Odrzuciłem ją na samym początku i teraz nie wiem sam hmm
nospor
23.03.2011, 09:23:40
To nie możesz sprawdzić? Zarzuć każdy kod w pętli, zmierz czasy, sprawdź jak skacze pamięć i będziesz wszystko wiedział.
ps:
$liczba_lini += substr_count($chunk, "\n");
przecież fread czyta plik po linijce, więc wystarczy:
$liczba_lini++;
redeemer
23.03.2011, 09:24:47
Rozwiązanie wc -l wydaje mi się być najbardziej optymalne. Jedynym minusem jest, że na takim Windowsie nie zadziała.
@nospor:
Chyba chodziło Ci o fgets?
nospor
23.03.2011, 09:31:02
Cytat
Chyba chodziło Ci o fgets?
http://pl.php.net/manual/en/function.fread.phpCytat
fread() reads up to length bytes from the file pointer referenced by handle. Reading stops as soon as one of the following conditions is met:
length bytes have been read
EOF (end of file) is reached
redeemer
23.03.2011, 09:32:54
EOF - End of file
Własnie robiłem testy i czasy są porównywalne, i nie wiem co wybrać.
Jeśli chodzi o drugą metodę to nie ma problemu bo to jest na Linux ale nie wiem jak to własnie jest z częstym wychodzeniem z php, czy to nie morduje serwera.
@nospor: twoje rozwiązanie jak słusznie zauważył @redeemer nie będzie działać.
nospor
23.03.2011, 09:37:31
Cytat
EOF - End of file
LOL..... sorki, skupiłem się tylko na End of

No to zamień fread na fgets i po sprawie

Cytat
Własnie robiłem testy i czasy są porównywalne, i nie wiem co wybrać.
Mógłbyś pokazać te testy? Znaczy jak je robiłeś, kod.
A cie proszę @nosper
$start = microtime(true);
Kod itp
print('czas wykonania: '.round((microtime(true) - $start), 5).' s');
nospor
23.03.2011, 09:46:26
Miałeś dać to w pętli np. 1000 razy i dla tej petli zmierzyć czas
Może zapytam inaczej czy użycie z trybu php funkcji powłoki jest wydajne.
Czy lepiej użyć wew. funkcji php?
Czyli co jest bardziej wydajne 1 czy 2 metoda.
@nosper zaraz sprawdzę
redeemer
23.03.2011, 09:47:14
Wykonaj testy na dużych plikach, bo na małych faktycznie może nie być widać różnicy.
Hmm w sumie nie spodziewałem się tego hmm
1. czas wykonania: 1.58546 s
2. czas wykonania: 7.57901 s
Różnica jest kolosalna
Pętla 1000 razy na pliku ok 3 tys lini
Co o tym sądzicie?
Czy czasami 1 metoda nie jest w pamięci przetrzymywana?
redeemer
23.03.2011, 10:32:58
Mi wyszło zupełnie co innego. Pętla 100 razy, plik: dump sql, 3351 linii, ~59MB. Skrypt uruchamiany z konsoli.
fread: 4.02844
wc -l: 1.77387
kiler129
25.03.2011, 07:25:57
Wykonanie kodu powłoki będzie wydajniejsze dla 1 dużego pliku ale wolniejsze dla wielu małych plików. Używanie exec() w pętlach to mordęga dla kodu (szczególnie na systemach wbudowanych - kto widział jak działa panel www NAS`ów firmy WD wie o czym mowa

).
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę
kliknij tutaj.