====== Rychlost regexu v různých jazycích ======
* Pomocné skripty přispívají k době zpracování korpusů
* Testované jazyky:
* ''flex''
* Perl
* Optimalizovaný Perl (pečlivě promyšlené pořadí příkazů, testy, na které řádky se má regex pustit atd.)
* Rust
* Testovaný skript: ''80_simpify_tags''
* Testovaný text: SYN2015 po vidu (''/store/corp/SYN2015-RC3/csts-rules-frazrl-rules1-rulh1-tag-vid'', 121.277.800 pozic)
* Stroj: ''grimm'' (Supermicro)
===== flex =====
* + Zkompilovaný jako C, velmi rychlý
* - Nezvládá utf-8
* - Nepřehledný
==== Zdrojový kód ====
%{
#include
#include
#include
unsigned char slovo[1500];
%}
%%
\]*\>.{14}8 {
strcpy(slovo,yytext);
slovo[yyleng-13]=0;
fprintf(yyout,"%s------------8",slovo);
}
\]*\>P7-.[34]--- {
strcpy(slovo,yytext);
slovo[yyleng-5]='-';
fprintf(yyout,"%s",slovo);
}
\]*\>P6-.[23467] {
strcpy(slovo,yytext);
slovo[yyleng-2]='-';
fprintf(yyout,"%s",slovo);
}
\]*\>P[1S]...[XZMIN][SP]3 {
strcpy(slovo,yytext);
slovo[yyleng-3]='-';
fprintf(yyout,"%s",slovo);
}
\]*\>P[1S]...FP3 {
strcpy(slovo,yytext);
slovo[yyleng-3]='-';
fprintf(yyout,"%s",slovo);
}
\]*\>Vs......[FPRX] {
strcpy(slovo,yytext);
slovo[yyleng-1]='-';
fprintf(yyout,"%s",slovo);
}
\]*\>Vc.X...3 {
strcpy(slovo,yytext);
slovo[yyleng-1]='-';
slovo[yyleng-5]='-';
fprintf(yyout,"%s",slovo);
}
\]*\>C\} {
strcpy(slovo,yytext);
slovo[yyleng-1]='=';
fprintf(yyout,"%s",slovo);
}
\]*\>VB-X---X....... {
strcpy(slovo,yytext);
slovo[yyleng-15]=0;
fprintf(yyout,"%sXX-------------",slovo);
}
\>[\-\+]?[0-9][^\<]*\]*\>[^\<]+\]*\>C[nlr].{13} {
strcpy(slovo,yytext);
slovo[yyleng-14]=0;
fprintf(yyout,"%s=-------------",slovo);
}
\]*\>co\]*\>P4... {
strcpy(slovo,yytext);
slovo[yyleng-3]=0;
fprintf(yyout,"%s---",slovo);
}
. ECHO;
\n ECHO;
%%
main()
{
yylex();
}
===== Perl =====
* + Přehledný regex
* - Nekompilovaný, pomalejší než C
==== Zdrojový kód ====
#!/usr/bin/perl
# use re 'debugcolor';
# use open ':utf8';
# use utf8;
# binmode( STDIN, ':utf8' );
# binmode( STDOUT, ':utf8' );
# binmode( STDERR, ':utf8' );
while ($radek = ) {
$radek =~ s/(]*>)P7-.([34]---)/$1P7--$2/g;
$radek =~ s/(]*>)P6-.([23467])/$1P6--$2/g;
$radek =~ s/(]*>Vs......)[FPRX]/$1-/g;
$radek =~ s/(]*>Vc.)X(...)3/$1-$2-/g;
if ($radek =~ /]*>co) {
$radek =~ s/(]*>P4).../$1---/g;
}
$radek =~ s/(>([\-\+])?[0-9][^<]*]*>[^<]+]*>)C[nlr]............./$1C=-------------/;
$radek =~ s/(]*>)C}/$1C=/g;
$radek =~ s/(]*>P[1S]...)[XZMIN]([SP]3)/$1-$2/g;
$radek =~ s/(]*>P[1S]...)F(P3)/$1-$2/g;
$radek =~ s/(]*>)VB-X---X......./$1XX-------------/g;
$radek =~ s/(]*>..)............8/$1------------8/g; # odkomentováno 27.7.2016: zkratky bez dalšího určení
print STDOUT "$radek";
}
===== Optimalizovaný Perl =====
* Regexy uspořádány do ''if - else'' bloků
* Testuje se, zda se má vůbec regex použít
* + Rychlejší než předchozí Perl
* - Trochu méně přehledný
==== Zdrojový kód ====
#!/usr/bin/perl
# use re 'debugcolor';
# use open ':utf8';
# use utf8;
# binmode( STDIN, ':utf8' );
# binmode( STDOUT, ':utf8' );
# binmode( STDERR, ':utf8' );
while ($radek = ) {
if ($radek =~ /]*>.{14}8/) {
$radek =~ s/(]*>..).{12}8/$1------------8/;
}
if ($radek =~ /]*>P[67]/) {
$radek =~ s/(]*>)P7-.([34]---)/$1P7--$2/g;
$radek =~ s/(]*>)P6-.([23467])/$1P6--$2/g;
}
elsif ($radek =~ /]*>P[1S]/) {
$radek =~ s/(]*>P[1S]...)[XZMIN]([SP]3)/$1-$2/g;
$radek =~ s/(]*>P[1S]...)F(P3)/$1-$2/g;
}
elsif ($radek =~ /]*>Vs/) {
$radek =~ s/(]*>Vs......)[FPRX]/$1-/g;
}
elsif ($radek =~ /]*>Vc/) {
$radek =~ s/(]*>Vc.)X(...)3/$1-$2-/g;
}
elsif ($radek =~ /]*>C[nlr]/) {
$radek =~ s/(>([\-\+])?[0-9][^<]*]*>[^<]+]*>)C[nlr]............./$1C=-------------/;
}
elsif ($radek =~ /]*>C}/) {
$radek =~ s/(]*>)C}/$1C=/;
}
elsif ($radek =~ /]*>VB-X/) {
$radek =~ s/(]*>)VB-X---X......./$1XX-------------/g;
}
elsif ($radek =~ /]*>co) {
$radek =~ s/(]*>P4).../$1---/g;
}
print STDOUT "$radek";
}
===== Rust =====
* První naivní pokus, žádná sláva
* - Nepřehledné
* - Pomalé
==== Zdrojový kód ====
extern crate lazy_static;
extern crate regex;
use std::io;
use regex::Regex;
use lazy_static::*;
fn main() {
loop {
let mut radek = String::new();
match io::stdin().read_line(&mut radek) {
Ok(0) => break,
Ok(_) => make_replacement(radek),
Err(e) => panic!(e)
}
// radek.clear();
}
}
fn make_replacement(mut radek: String) {
lazy_static! {
static ref ABBR_REGEX:
Regex = Regex::new(r"(?P]*>..).{12}8").unwrap();
static ref P7_REGEX:
Regex = Regex::new(r"(?P]*>P7-).(?P[34]---)").unwrap();
static ref P6_REGEX:
Regex = Regex::new(r"(?P]*>P6-).(?P[23467])").unwrap();
static ref P1SX_REGEX:
Regex = Regex::new(r"(?P]*>P[1S]...)[XZMIN](?P[SP]3)")
.unwrap();
static ref P1SF_REGEX:
Regex = Regex::new(r"(?P]*>P[1S]...)F(?PP3)").unwrap();
static ref VS_REGEX:
Regex = Regex::new(r"(?P]*>Vs......)[FPRX]").unwrap();
static ref VC_REGEX:
Regex = Regex::new(r"(?P]*>Vc.)X(?P...)3").unwrap();
static ref CNLR_REGEX:
Regex = Regex::new(r"(?P>([\-\+])?[0-9][^<]*]*>[^<]+]*>C)[nlr](?P.{13})")
.unwrap();
static ref CROM_REGEX:
Regex = Regex::new(r"(?P]*>C)\}").unwrap();
static ref VBX_REGEX:
Regex = Regex::new(r"(?P]*>)VB-X---X.{7}").unwrap();
static ref CO_REGEX:
Regex = Regex::new(r"(?P]*>co]*>P4)...").unwrap();
}
let mut after = ABBR_REGEX.replace_all(&radek, "$f------------8")
.to_string();
radek = after;
after = P7_REGEX.replace_all(&radek, "$f-$s").to_string();
radek = after;
after = P6_REGEX.replace_all(&radek, "$f-$s").to_string();
radek = after;
after = P1SX_REGEX.replace_all(&radek, "$f-$s").to_string();
radek = after;
after = P1SF_REGEX.replace_all(&radek, "$f-$s").to_string();
radek = after;
after = VS_REGEX.replace_all(&radek, "$f-").to_string();
radek = after;
after = VC_REGEX.replace_all(&radek, "$f-$s-").to_string();
radek = after;
after = CNLR_REGEX.replace_all(&radek, "$f=-------------").to_string();
radek = after;
after = CROM_REGEX.replace_all(&radek, "$f=").to_string();
radek = after;
after = VBX_REGEX.replace_all(&radek, "$fXX-------------").to_string();
radek = after;
after = CO_REGEX.replace_all(&radek, "$f---").to_string();
radek = after;
after = P1SF_REGEX.replace_all(&radek, "$f-$s").to_string();
radek = after;
print!("{}",radek);
}
===== Porovnání =====
^ Porovnání jazyků ^^^^^
| | 1byte || utf8 ||
^ flex | 3m58.761s | 100 % | NA ||
^ Perl | 6m36.372s | 166 % | 14m29.309s | 364 % |
^ Opt. Perl | 4m50.576s | 122 % | 9m47.725s | 246 %|
^ Rust | NA || 9m07.683s | 229 % |