Возникла потребность обойти посимвольно строку в ~70000 символов.
Не задумываясь пишу код:
<?php $time_start = microtime(true); $i = 0; $char = ''; $str = '<loop i = 1 to 70000>A</loop>'; for($i=0; $i<=mb_strlen($str, 'utf-8'); $i++) { $char = mb_substr($str, $i, 1, 'utf-8'); } echo 'Прошло ' . ( microtime(true) - $time_start ) . ' секунд'; ?>
Получаю совершенно "волшебное" время:
Прошло 39.139607191086 секунд
Немного подумав...
<?php $time_start = microtime(true); $i = 0; $char = ''; $str = '<loop i = 1 to 70000>A</loop>'; $condition = mb_strlen($str, 'utf-8'); for($i=0; $i<=$condition; $i++) { $char = mb_substr($str, $i, 1, 'utf-8'); } echo 'Прошло ' . ( microtime(true) - $time_start ) . ' секунд'; ?>
Время все еще "прелесно":
Прошло 13.274945020676 секунд
Забавно получается. Вызов mb_strlen 70к раз занимает примерно 26 секунд. Есть повод поизучать исходники php. Не думал, что длинна строки будет обсчитываться каждый раз.
Ооооокеееей. Раз все равно будем обходить посимвольно, преобразуем строку в массив.
<?php $time_start = microtime(true); $i = 0; $char = ''; $str = '<loop i = 1 to 70000>A</loop>'; $str = preg_split('//u', $str); $condition = count($str); for($i=0;$i<=$condition;$i++) { $char = $str[$i]; } echo 'Прошло ' . ( microtime(true) - $time_start ) . ' секунд'; ?>
Профит. Примерно это и ожидал увидеть.
Прошло 0.073200941085815 секунд
Тестировал на php 5.2.17 (собранном в 2012) и 5.4.0 (собранном сегодня
21.12.12 (Happy Doomsday!)). На php 5.2.5 (собранном в 2009) preg_split выдает
все те же ~40 секунд. Так что обновляйтесь .