Эффективность регулярного выражения.

| Нет комментариев | Нет трекбэков

Вы написали скрипт или даже большой какой-то проект. Наверняка в нем используются регулярные выржания. И наверняка вы захотели бы оптимизировать ваш проект по скорости выполнения. Начните с опимизации "регулярок". Для этого вам очень пригодится прагма use re, с опцией 'debug', и возможно qr//.

Я не буду подробно рассказывать о qr//, для предварительной компиляции regexp'ов, (может быть в другой раз), а расскажу о такой полезной прагме как: use re с опцией debug. В скриптах она используется так:

#!/usr/bin/perl -w
use strict;
use re 'debug';

При включении этой прагмы все регулярные выражения будут выдавать о себе много интересной информации. И оценивая эту информацию можно повысить скорость обработки входных данных для вашего регэкспа.

Предположим у вас есть вот такой вот код, который извлекает кодировку из заголовка content-type:
   1    #!/usr/bin/perl -w
   2    use strict;
   3    use re 'debug';
   4    
   5    my $string='text/html; charset=UTF-8;';
   6    
   7    my $reg=qr/charset=(\w+-\w+)/i;
   8    
   9    if($string=~/$reg/)
  10    {
  11        print "find $1\n";
  12    } else {
  13        print "not\n";
  14    }

 Запустим его на выполнение с прагмой use re 'debug':

Compiling REx `charset=(\w+-\w+)'
size 14 Got 116 bytes for offset annotations.
first at 1
   1: EXACTF <charset=>(4)
   4: OPEN1(6)
   6:   PLUS(8)
   7:     ALNUM(0)
   8:   EXACTF <->(10)
  10:   PLUS(12)
  11:     ALNUM(0)
  12: CLOSE1(14)
  14: END(0)
stclass "EXACTF <charset=>" minlen 11
Offsets: [14]
        1[8] 0[0] 0[0] 9[1] 0[0] 12[1] 10[2] 13[1] 0[0] 16[1] 14[2] 17[1] 0[0] 18[0]
Matching REx "charset=(\w+-\w+)" against "text/html; charset=UTF-8;"
Matching stclass "EXACTF <charset=>" against "text/html; charset=UTF-8;"
  Setting an EVAL scope, savestack=7
  11 <tml; > <charset>    |  1:  EXACTF <charset=>
  19 <arset=> <UTF-8;>    |  4:  OPEN1
  19 <arset=> <UTF-8;>    |  6:  PLUS
                           ALNUM can match 3 times out of 2147483647...
  Setting an EVAL scope, savestack=7
  22 <arset=UTF> <-8;>    |  8:    EXACTF <->
  23 <arset=UTF-> <8;>    | 10:    PLUS
                           ALNUM can match 1 times out of 2147483647...
  Setting an EVAL scope, savestack=7
  24 <arset=UTF-8> <;>    | 12:      CLOSE1
  24 <arset=UTF-8> <;>    | 14:      END
Match successful!
find UTF-8
Freeing REx: `"charset=(\\w+-\\w+)"'

Теперь немного изменим наше выражение:

   7    my $reg=qr/charset=([\w,-]+)/i;

и снова запустим с отладкой:

Compiling REx `charset=([\w,-]+)'
size 21 Got 172 bytes for offset annotations.
first at 1
   1: EXACTF <charset=>(4)
   4: OPEN1(6)
   6:   PLUS(19)
   7:     ANYOF{i}[,\-0-9A-Z_a-z+utf8::IsWord](0)
  19: CLOSE1(21)
  21: END(0)
stclass "EXACTF <charset=>" minlen 9
Offsets: [21]
        1[8] 0[0] 0[0] 9[1] 0[0] 16[1] 10[6] 0[0] 0[0] 0[0] 0[0] 0[0] 0[0] 0[0] 0[0] 0[0] 0[0] 0[0] 17[1] 0[0] 18[0]
Matching REx "charset=([\w,-]+)" against "text/html; charset=UTF-8;"
Matching stclass "EXACTF <charset=>" against "text/html; charset=UTF-8;"
  Setting an EVAL scope, savestack=7
  11 <tml; > <charset>    |  1:  EXACTF <charset=>
  19 <arset=> <UTF-8;>    |  4:  OPEN1
  19 <arset=> <UTF-8;>    |  6:  PLUS
                           ANYOF{i}[,\-0-9A-Z_a-z+utf8::IsWord] can match 5 times out of 2147483647...
  Setting an EVAL scope, savestack=7
  24 <arset=UTF-8> <;>    | 19:    CLOSE1
  24 <arset=UTF-8> <;>    | 21:    END
Match successful!
find UTF-8
Freeing REx: `"charset=([\\w,-]+)"'

Разница очевидна. Второе выражение отработало быстрее. Как на этапе компиляции (выделено жирным), так и на этапе выполнения (второму варианут потребовалось 2 прохода, в то время как первому 3!). Так - методом подбора можно оптимизировать некоторые свои регэкспы, или во всяком случае увидеть наиболее неэффективные из них.

Еще некоторую информацию вы сможете почерпнуть отсюда.

 

Нет трекбэков

URL для трекбэков: http://perlmonks.org.ru/cgi-bin/MT/engine/mt-tb.cgi/12

Комментировать

Об этой записи

Сообщение опубликовано 13.04.2009 11:40. Автор — Monks.

Предыдущая запись — Perl6 под Windows. Это просто!

Следующая запись — Grab-killer или убиваем граберы контента.

Смотрите новые записи на главной странице или загляните в архив, где есть ссылки на все сообщения.

Страницы


 


 

Page copy protected against web site content infringement by Copyscape