[image]

PHP: ускоряем программы, меняя substr на preg_*

 
+
-
edit
 

Balancer

администратор
★★★★★
>Привет, на ЛОРе наткнулся на твои комментарии по поводу модернизации smarty - замены substr-ов на preg
>Не мог бы ты рассказать об этом по подробнее? Или у тебя случайно нет статьи/твоей версии smarty в свободном доступе?

Рассказываю :)

В PHP очень тормозной substr. Как в прямом виде, так и в виде $str{$pos}.

После того, как я отбенчил Smarty, выяснилось, что там основную часть времени занимают вызовы susbtr().

Дальше я тупо отыскал все вхождения substr и поменял, где это возможно, на альтернативы. Или не тупо, а самые тормозящие... Не помню уже.

Самое простое. Сравнения, вида:

if($path{0} == '/')
меняем на
if(preg_match('!^/!', $path))

или

if(substr($file, -4) == '.php')
меняем на
if(preg_match('!\.php$!', $file))

Подобных примеров там немало.

Местами можно было и более эффективно менять. Что-то в духе... ладно, пойду пороюсь :)

Вот реальные примеры:
if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
замена:
if(preg_match("!^\*.+\*$!", $template_tag))

code php
  1. if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") {
  2.     $compiled_content = substr($compiled_content, 0, -1);
  3. }


замена:
$compiled_content = preg_replace("!\n$!", "", $compiled_content);
(хотя, возможно, что можно и тупо $compiled_content = rtrim($compiled_content) - но лениво разбираться, вдруг там пробелы справа где-то значмиые?)

if (substr($tag_command, 0, 1)=='/')
замена на
if (preg_match("!^/!", $tag_command))

более хитрая замена:
code php
  1. if(is_numeric(substr($var_expr, 0, 1)))
  2.     $_var_ref = $var_expr;
  3. else
  4.     $_var_ref = substr($var_expr, 1);

на
$_var_ref = preg_replace("!^\D!", "", $var_expr);

и т.д...

Если мне память не изменяет, таким образом я добился где-то пятикратного ускорения работы шаблонизатора.

К сожалению, такой правке подвергалась только версия 2.6.18, до более свежих руки не доходят :) А отослать патчи разработчикам - ломает. Не помню ещё ни одного случая, чтобы мои патчи на что-то принимались кем-то. Может, мой «английский» вызывает слишком много недоверия ;)
   
+
-
edit
 

Murkt

Pythoneer

Balancer> В PHP очень тормозной substr. Как в прямом виде, так и в виде $str{$pos}.

Balancer> Если мне память не изменяет, таким образом я добился где-то пятикратного ускорения работы шаблонизатора.

Я не знаю что хуже - то, что в PHP тормозной выбор подстрок, или то, что авторы Смарти не удосужились даже попрофайлить своё детище. Наверное, это общий тренд большинства PHP-писателей :-)

Я вот только что вспомнил, что в Джаваскрипте, вроде, регэкспами тоже сильно быстрее... По крайней мере highlight.js Сагалаева парсит код при помощи регэкспов, и он говорит что это именно потому, что посимвольно выходит очень медленно.

Задумался, а как же в питоне?

code python
  1. a = """hkh fdu agcv gvyu yeeh 4r2y s zciod hjkds hfjk <code> fdsfh yui xhk jk iuvcu vxz v sfg sa.html"""
  2. a[:-5] == '.html' # первый вариант
  3.  
  4. import re
  5. r = re.compile('\.html$')
  6. r.search(a) # второй вариант
  7.  
  8. re.search('\.html$', a) # третий вариант

Если выполнить миллион раз первый вариант - четверть секунды (0.257), второй вариант - в пять раз дольше (1.246). Третий вариант выполняется ещё раза в три дольше (3.198).
   
+
-
edit
 

Balancer

администратор
★★★★★
Murkt> Задумался, а как же в питоне?

Я в прошлом году Питон тестировал на этот счёт. Там подстроки быстрее. Тоже на ЛОРе, кажется, цифры выкладывал.
   
RU Balancer #23.04.2008 12:13  @Balancer#23.04.2008 12:07
+
-
edit
 

Balancer

администратор
★★★★★
Balancer> Я в прошлом году Питон тестировал на этот счёт.

А, нет, на ЛОРе я тестировал замену, а не подстроки: Новости - OpenSource - Готовимся к PHP6
   

в начало страницы | новое
 

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22

Warning: A non-numeric value encountered in /var/www/bors/composer-tests/vendor/balancer/airbase-bors/src/Modules/Anniversary.php on line 22
Народные приметы сегодня: Ранняя весна – половодья жди
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru