Я хотел бы выполнить сопоставление с образцом в файле (около 200 мегабайт), а затем вставить в массив совпадающие строки, а также произвольное количество строк до и после каждой совпадающей строки.
sub1,использование perl grep, занимает 11 секунд
sub2, который использует unix egrep, 1 секунду
sub6 (ack) 50 секунд (это быстрее, если вы не используете якоря \ b, \ sи т. д.)
ack из командной строки занимает 15 секунд
Меня интересуют предложения по ускорению sub1 или поиску быстрого решения perl, которое не зависит от внешнегоtools
Кажется, что perl grep намного медленнее, чем unix.
"index" действительно быстрее, чем регулярные выражения (но мне нужны \ b, \ s и т. д.)
http://www.perlmonks.org/?node_id=885174
http://www.perlmonks.org/?node_id=957554
спасибо
use 5.014;
use strict;
use warnings;
use Time::HiRes qw(usleep ualarm gettimeofday tv_interval);
use List::MoreUtils qw(uniq);
open FILE, '<textMatchInAfile.txt' or die;
my $p = '\bsala|che|relazione|di|questo|coso|^qui\$';
my $mR = 1; #print more rows before - after the matching
my @n = <FILE>;
&sub1( $p, $mR, @n ); #suggest: insert references
&sub3( $p, $mR );
sub sub1 { #questa sub usa perl grep
my $p = $_[0]; #pattern
my $mR = $_[1]; #more rows
my @n = @_[ 2 .. $#_ ]; #input File
my $time = [gettimeofday];
my @new = grep { $n[$_] =~ /$p/ } 0 .. $#n;
my @unique =
map { @n[ $_ - $mR .. $_ + $mR ] } @new[ 0 + $mR .. $#new - $mR];
say "\n" . 'time sub1 perl grep: ' . tv_interval($time);
@unique = uniq(@unique);
say "sub 1 $#unique";
}
sub sub3 { #unix grep with color and line numbers
my $p = $_[0];
my $mR = $_[1];
my $cmd = "grep -n -C $mR"; #with line numbers
$p =~ s/\|/ /g;
$p =~ s/\h+/" -e "/g;
$p = ' -e "' . $p . '" ';
say "cmd ===$cmd=== ss ===$p===";
my @values;
$values[0] = $p;
$values[1] = ( ' ' . 'textMatchInAfile.txt' );
my $time = [gettimeofday];
my @valori = `$cmd @values` or die "system @values` failed: $?";
say 'sub3 egrep shell: ' . $#valori;
say 'time sub3 tempo trovati con egrep shell ' . tv_interval($time);
my @uniq_list = uniq(@valori);
}
sub sub6 { #perl ack
my $p = $_[0]; #pattern
my $mR = $_[1]; #more rows
my @values;
my $time = [gettimeofday];
my @valori = qx (ack -C $mR "$p" textMatchInAfile.txt)
or die "system @values` failed: $?";
say 'number of values found with ack' . $#valori;
say 'time sub6 ack' . tv_interval($time);
}
#
#this one takes 11 seconds
use 5.014;
use warnings;
use Time::HiRes qw(usleep ualarm gettimeofday tv_interval);
my @array;
my $pattern = '\bsala|che|relazione|di|questo|coso|^qui\$';
open( my $filehandle, "<textMatchInAfile.txt" );
my $time = [gettimeofday];
while (<$filehandle>) {
if ( $_ =~ /$pattern/ ) {
push @array;
}
}
say 'time while' . tv_interval($time);
ОК, Unix grep на порядокбыстрее, чем Perl Grep, я буду жить с этим.