digitorum.ru

Как меня найти

Профиль

icq: 4415944

Работа со строками в php.

php

Возникла потребность обойти посимвольно строку в ~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 секунд. Так что обновляйтесь .