To moje řešení trvá tak dlouho díky použitýmu kódování. UTF-8 nemá pevnou délku znaku a tam nejde skákat rozumně doprostřed řetězce indexem. A na to jsem zapoměl.
Řešením je počítat v mb_string s nějakym kódováním s pevnym znakem, např. UCS-2. Pak je to najednou rychlejší, dle mejch testů cca 2x rychlejší:
2,5s ku 4,7s.
Problém je, že vstupní texty budou pravděodobně v UTF-8 a pak teda je nutné dělat dvojí konverzi (na vstupu a výstupu fce), takže se rychlost smrskne na
3,9s ku 4,7s
a tady je už asi rychlejší použít ten substring. I když todle řešení je robustnější, tamto bude při velkym počtu vyhledanejch řetězců (popř. vyhledávanejch řetězců, kde zas stačí jeden UTF/UCS převod) zpomalovat víc, tam se projeví rychlost kódování UCS-2 (zkoušel jsem jen svůj algoritmus, při vyhledání 'a' byl najednou rozdíl
mezi UCS a UTF-8 1 ku 5,9s (menší počet iterací).
Ideální by bylo, kdyby (mb_)substr řetěazce nekopíroval, ale to bychom chtěli od php příliš....
Jo, ještě v těch řešeních je nadužívání mb_strlen - vzhledem k tomu, že u mb se musí projít celej řetězec, tak tam to vadí, i když jsem předtim tvrdil, že ne... :-(
Ad na klientu: Šlo by to i zkombinovat: na serveru převést utf8 na ascii a na klientu to zvýraznit :-)
PS: Jo a UCS-2 nemá všechny znaky, takže přijdeš o starou čínštinu apod... UCS-4 to řeší, ale to by bylo zas pomalejší, přecijenom cca 3x větší paměťový nároky se poznaj....