Cytat(zegarek84 @ 1.11.2008, 16:42:04 )

a czemu do np. piątego znaku nie odwołasz po prostu mb_substr($string,4,1,'utf-8')

z powodów jakie wymieniłem wyżej. Chce przeparsować string zakodowany w utf8. Nie chcę jakiegokolwiek rozwiązania, tylko rozwiazanie estetyczne z punktu widzenia optymalności. Rozwiązanie nazujące na mb_substr wygląda tak:
<?php
for($i=0; $i<mb_strlen($napis); $i++)
$x = mb_substr($napis,$i,1);
?>
Podejrzewam, że mb_substr musi przejść po całym $napis aż do pozycji $i. Zatem powyższe rozwiązanie ma złożoność O(N^2) a nie O(N) - a tego drugiego oczekujemy po przetwarzaniu tekstu znak po znaku. Zrobiłem eksperyment żeby potwierdzić albo rozwiać podejrzenia. Odpalam skrypt testowy, który przechodzi kolejno po napisach zakodowanych w utf8 odpowiednio długości: 1000 znakow, 2000, 3000,...aż do stringów 50000 znakowych. Sprawdzam zależność czasu wykonywania od długości stringa.
<?php
mb_internal_encoding("UTF-8");
// przygotowanie napisu o długości 1000*50 = 50 0000 znaków
$napis = '';
for($i = 0; $i<1000; ++$i)
$napis .= 'aaa中国6789łłłłłłłłłł*()&^%#@%!qwertyQWERTYóżźćXXłłż';
echo 'liczba znaków w stringu: ' . $rmax = mb_strlen
($napis) . "<br>\n";
// przejście znak po znaku przez napisy o długości $p=1000,2000,3000,... < 50000 znaków
for($p = 1000; $p < $rmax; $p += 1000)
{
echo 'napis długości:' . $p; for($iter = 1; $iter < $p; ++$iter) // tu przechodzimy znak po znaku
{
$x = mb_substr($napis,$iter,1);
}
$czas_wykonania[$p] = ($czas_stop - $czas_start);// / $iteracje;
echo ', czas wykonania: ' . $czas_wykonania[$p] . "<br>\n"; }
echo 'KONIEC, teraz zapiszemy wynik do pliku CSV';
$p = fopen('wynik.txt','wb'); if($p === FALSE)
throw new Exception('PLIK, PLIK!!!');
// zapis na plik
foreach($czas_wykonania as $dlugoscstr => $czaswyk)
{
if(fputcsv
($p, array($dlugoscstr,$czaswyk)) === FALSE) throw new Exception('PLIK, PLIK!!!');
}
?>
w wyniku otrzymałem:
liczba znaków w stringu: 50000
napis długości:1000, czas wykonania: 0.045909881591797
napis długości:2000, czas wykonania: 0.11165714263916
napis długości:3000, czas wykonania: 0.22915983200073
napis długości:4000, czas wykonania: 0.24982881546021
napis długości:5000, czas wykonania: 0.3840639591217
napis długości:6000, czas wykonania: 0.48809003829956
napis długości:7000, czas wykonania: 0.60801005363464
napis długości:8000, czas wykonania: 0.83047580718994
napis długości:9000, czas wykonania: 0.93301296234131
napis długości:10000, czas wykonania: 1.0732500553131
napis długości:11000, czas wykonania: 1.2416779994965
napis długości:12000, czas wykonania: 1.4608471393585
napis długości:13000, czas wykonania: 1.7372689247131
napis długości:14000, czas wykonania: 1.895831823349
napis długości:15000, czas wykonania: 2.1436331272125
napis długości:16000, czas wykonania: 2.385999917984
napis długości:17000, czas wykonania: 2.6672129631042
napis długości:18000, czas wykonania: 2.9463531970978
napis długości:19000, czas wykonania: 3.1730628013611
napis długości:20000, czas wykonania: 3.5410470962524
napis długości:21000, czas wykonania: 3.8248689174652
napis długości:22000, czas wykonania: 4.1826858520508
napis długości:23000, czas wykonania: 4.5365719795227
napis długości:24000, czas wykonania: 4.915678024292
napis długości:25000, czas wykonania: 5.2788889408112
napis długości:26000, czas wykonania: 5.6325259208679
napis długości:27000, czas wykonania: 6.0388510227203
napis długości:28000, czas wykonania: 6.462660074234
napis długości:29000, czas wykonania: 6.9221448898315
napis długości:30000, czas wykonania: 7.2982220649719
napis długości:31000, czas wykonania: 7.8054759502411
napis długości:32000, czas wykonania: 8.2694098949432
napis długości:33000, czas wykonania: 8.7420930862427
napis długości:34000, czas wykonania: 9.2250289916992
napis długości:35000, czas wykonania: 9.7165539264679
napis długości:36000, czas wykonania: 10.300148010254
napis długości:37000, czas wykonania: 10.80548620224
napis długości:38000, czas wykonania: 11.390262126923
napis długości:39000, czas wykonania: 11.927836179733
napis długości:40000, czas wykonania: 12.468158960342
napis długości:41000, czas wykonania: 13.08842086792
napis długości:42000, czas wykonania: 13.647618055344
napis długości:43000, czas wykonania: 14.36807012558
napis długości:44000, czas wykonania: 14.909945964813
napis długości:45000, czas wykonania: 15.589555025101
napis długości:46000, czas wykonania: 16.189097166061
napis długości:47000, czas wykonania: 17.128329992294
napis długości:48000, czas wykonania: 17.590538978577
napis długości:49000, czas wykonania: 19.319259881973
KONIEC, teraz zapiszemy wynik do pliku CSV
a po zrobieniu wykresu z pliku CSV:
http://img201.imageshack.us/my.php?image=zlozzc1.gif czyli złożoność algorytmu z mb_substr traktowanym jako "nextchar" jest na oko kwadratowa. Potwierdzają się więc moje podejrzenia.