Rychlost GNU rx, GNU regex

Daniel Skarda 0rfelyus na atrey.karlin.mff.cuni.cz
Čtvrtek Leden 14 11:56:36 CET 1999


Ahoj,

  chtel bych se zeptat, jestli nekdo nema zkusenosti s ruznymi balicky
implementujicimi regularni vyrazy. Ja jsem vyzkousel dve implementace
(staricky GNU regex (tj regex.c, regex.h) a implementaci POSIXovych
regcomp & regexec (z GNU rx ci z libc)) a jelikoz jsem chtel prozkoumat
rychlost jednotlivych implementaci, napsal jsem dva kratke programky.

  Vysledky, ktere jsem obdrzel, me dost zmatly - a rad bych se tedy
zeptal nejakeho "regularniho" odbornika, co si o nich mysli a proc se
dosazene casy tak lisily.

   [Casti kodu jsem pripojil na konec mailu, pokud byste chteli cele
zdrojaky, dal jsem je na ftp://atrey.karlin.mff.cuni.cz/pub/local/0rfelyus/regex-experiments]

   A ted podivne vysledky:

    GNU regex (testregex.c): 5 sec (AMD 586/133, 32 MB EDO)
    GNU rx (testrx.c): 28 sec 
   
  Pokud jsem v testrx napsal misto REG_EXTENDED flagu napsal 0 (a
nahradil "(" za "\\(" atd) vysledek se nezmenil. Pokud jsem "(" ")"
zcela vypustil, testrx bezelo 7 sec.

  Byl bych vdecny za jakekoliv svetlo do mne obklopujici tmy 
z regularnich vyrazu (resp vykonu jejich implementaci).


Dik,
Dan


spolecny kod:
-------------
   char *t = "Pes jitrnicku sezral, docela ..... /* celkem asi 240 znaku */

   char *r1 = "ko(pa)*li";
   char *r2 = "desce.*$";
   char *r3 = " [:alpha:]+v";     /* gnu rozsireni -=> nic se nenajde */
   char *r4 = "[potvra]{4,10}";
	

textrx.c:                             
---------
				      
  regcomp ( &re1, r1,  REG_EXTENDED); 
  regcomp ( &re2, r2,  REG_EXTENDED); 
  regcomp ( &re3, r3,  REG_EXTENDED); 
  regcomp ( &re4, r4,  REG_EXTENDED); 
				      
  for (i = 0; i < 10000; i++)	      
    {				      
      regexec ( &re1, t1, 1, &res, 0);
      regexec ( &re2, t1, 1, &res, 0);
      regexec ( &re3, t1, 1, &res, 0);
      regexec ( &re4, t1, 1, &res, 0);
    }                                 

testregex.c:
------------

  re1.buffer = malloc (32); re1.allocated = 32;  re1.translate = NULL;
  re2.buffer = malloc (32); re2.allocated = 32;  re2.translate = NULL;
  re3.buffer = malloc (32); re3.allocated = 32;  re3.translate = NULL;
  re4.buffer = malloc (32); re4.allocated = 32;  re4.translate = NULL;

  re_syntax_options = (RE_INTERVALS | RE_NO_BK_BRACES | RE_SYNTAX_AWK) & (~ RE_NO_BK_REFS);

  re_compile_pattern ( r1, strlen (r1), &re1);
  re_compile_pattern ( r2, strlen (r2), &re2);
  re_compile_pattern ( r3, strlen (r3), &re3);
  re_compile_pattern ( r4, strlen (r4), &re4);

  re1.fastmap = (char *) malloc (256);
  re2.fastmap = (char *) malloc (256);
  re3.fastmap = (char *) malloc (256);
  re4.fastmap = (char *) malloc (256);

  range = strlen (t1);

  for (i = 0; i < 10000; i ++)
    {
      re_search ( &re1, t1, range, 0, range, NULL);
      re_search ( &re2, t1, range, 0, range, NULL);
      re_search ( &re3, t1, range, 0, range, NULL);
      re_search ( &re4, t1, range, 0, range, NULL);
    }
  


Další informace o konferenci Linux