我试图找出用 perl分割 CLF 格式行(apache access.log 文件中的链接)的最快方法。多年来,他们已经积累了数百万。以下是我到目前为止测试过的内容。我的最后一次尝试已经比使用正则表达式更快了。
但是 - 你怎么看 -有没有办法更快地做到这一点?
1 2 3 4 - - 13/Jun/2007:03:20:15 +0200 GET / ..?,-" HTTP/1.0 200 202
1: [16909060] [1181697615] [GET / ..?,-" HTTP/1.0]
1.2.3.4 - - 13/Jun/2007:03:20:15 +0200 GET / ..?,-" HTTP/1.0 200 202
2: [16909060] [1181697615] [GET / ..?,-" HTTP/1.0]
202 200 1.2.3.4 - - 13/Jun/2007:03:20:15 +0200 GET / ..?,-" HTTP/1.0
3: [16909060] [1181697615] [GET / ..?,-" HTTP/1.0]
1.2.3.4 - - 13/Jun/2007:03:20:15 +0200 GET / ..?,-" HTTP/1.0 200 202
4: [16909060] [1181697615] [GET / ..?,-" HTTP/1.0]
GET / ..?,-" HTTP/1.0 13/Jun/2007:03:20:15 +0200 1.2.3.4 - - 200 202
5: [16909060] [1181697615] [GET / ..?,-" HTTP/1.0]
13/Jun/2007:03:20:15 +0200 GET / ..?,-" HTTP/1.0 1.2.3.4 - - 200 202
6: [16909060] [1181697615] [GET / ..?,-" HTTP/1.0]
---- hit <ENTER> to start Test ----
Benchmark: timing 100000 iterations of Method 1, Method 2, Method 3,
Method 4, Method 5, Method 6...
1: 39 wallclock s(37.64usr + 0.12sys = 37.77CPU) @2647.81/s(n=100000)
2: 39 wallclock s(38.35usr + 0.19sys = 38.53CPU) @2595.18/s(n=100000)
3: 39 wallclock s(37.19usr + 0.14sys = 37.33CPU) @2678.74/s(n=100000)
4: 38 wallclock s(36.80usr + 0.08sys = 36.88CPU) @2711.57/s(n=100000)
5: 38 wallclock s(36.93usr + 0.14sys = 37.07CPU) @2697.89/s(n=100000)
6: 38 wallclock s(36.11usr + 0.16sys = 36.27CPU) @2757.10/s(n=100000)
8X----------------
#!/usr/bin/perl -w
use strict;
use warnings;
use FileHandle;
use Date::Parse;
use Benchmark;
STDOUT->autoflush(1); #....................................... autoflush STDOUT
our $s='1.2.3.4 - - [13/Jun/2007:03:20:15 +0200] "GET / ..?,-" HTTP/1.0" 200 202';
our (@T,$host,$timestamp,$request);
print "---- test functionality -----------------------------------\n";
split1(); print join(" ",@T)."\n1: [$host] [$timestamp] [$request]\n";
split2(); print join(" ",@T)."\n2: [$host] [$timestamp] [$request]\n";
split3(); print join(" ",@T)."\n3: [$host] [$timestamp] [$request]\n";
split4(); print join(" ",@T)."\n4: [$host] [$timestamp] [$request]\n";
split5(); print join(" ",@T)."\n5: [$host] [$timestamp] [$request]\n";
split6(); print join(" ",@T)."\n6: [$host] [$timestamp] [$request]\n";
print "---- hit <ENTER> to start Test ----"; <>;
timethese (
100000,
{'1' => '&split1',
'2' => '&split2',
'3' => '&split3',
'4' => '&split4',
'5' => '&split5',
'6' => '&split6',
}
);
exit(0);
1;
sub split1
{ $host='';$timestamp='';$request='';@T=();
#----------------------------------------------------------------------------
@T = $s =~ m/^(\d+)\.(\d+)\.(\d+)\.(\d+) (\S+) (\S+) \[(.+)\] "(\S+) (.*?) (\S+)" (\S+) (\S+)$/;
#----------------------------------------------------------------------------
$host=unpack("N",pack("C4",@T));
$timestamp=str2time($T[6]);
$request=join(" ",$T[7],$T[8],$T[9]);
}
sub split2
{ $host='';$timestamp='';$request='';@T=();
#----------------------------------------------------------------------------
@T=split(/ /,$s);
splice(@T,5,@T-7,join(" ",@T[5..(@T-3)]));
splice(@T,3,2 ,join(" ",@T[3..4 ]));
chomp($T[6]); $T[3]=substr($T[3],1,-1); $T[4]=substr($T[4],1,-1);
#----------------------------------------------------------------------------
$host=unpack("N",pack("C4",split(/\./,$T[0])));
$timestamp=str2time($T[3]);
$request=$T[4];
}
sub split3
{ $host='';$timestamp='';$request='';@T=();
#----------------------------------------------------------------------------
my $i; my $x=$s;
$i=rindex($x,' ');push(@T,substr($x,$i+1)); $x=substr($x,0,$i);
$i=rindex($x,' ');push(@T,substr($x,$i+1)); $x=substr($x,0,$i);
$i=index($x,' ');push(@T,substr($x,0,$i)); $x=substr($x,$i+1,-1);
$i=index($x,' ');push(@T,substr($x,0,$i)); $x=substr($x,$i+1);
$i=index($x,' ');push(@T,substr($x,0,$i)); $x=substr($x,$i+2);
$i=index($x,']');push(@T,substr($x,0,$i)); push(@T,substr($x,$i+3));
#----------------------------------------------------------------------------
$host=unpack("N",pack("C4",split(/\./,$T[2])));
$timestamp=str2time($T[5]);
$request=$T[6];
}
sub split4
{ $host='';$timestamp='';$request='';@T=();
#----------------------------------------------------------------------------
my $i; my $x=$s;
$i=rindex($x,' ');$T[6]=substr($x,$i+1); $x=substr($x,0,$i);
$i=rindex($x,' ');$T[5]=substr($x,$i+1); $x=substr($x,0,$i);
$i= index($x,' ');$T[0]=substr($x,0,$i); $x=substr($x,$i+1,-1);
$i= index($x,' ');$T[1]=substr($x,0,$i); $x=substr($x,$i+1);
$i= index($x,' ');$T[2]=substr($x,0,$i); $x=substr($x,$i+2);
$i= index($x,']');$T[3]=substr($x,0,$i); $T[4]=substr($x,$i+3);
#----------------------------------------------------------------------------
$host=unpack("N",pack("C4",split(/\./,$T[0])));
$timestamp=str2time($T[3]);
$request=$T[4];
}
sub split5
{ $host='';$timestamp='';$request='';@T=();
#----------------------------------------------------------------------------
my ($i,$j); my $x=$s;
$i=index($x,'"')+1;
$j=rindex($x,'"');
$T[0]=substr($x,$i,$j-$i);
my $a=substr($x,0,$i-3);
$i=rindex($a,'[');
$T[1]=substr($a,$i+1); $a=substr($a,0,$i-1);
$x=$a.substr($x,$j+1);
push(@T,split(/ /,$x));
#----------------------------------------------------------------------------
$request=$T[0];
$timestamp=str2time($T[1]);
$host=unpack("N",pack("C4",split(/\./,$T[2])));
}
sub split6
{ $host='';$timestamp='';$request='';@T=();
#----------------------------------------------------------------------------
my ($i,$j); my $x=$s;
$i=index($x,'[');
$j=rindex($x,'"');
$T[0]=substr($x,$i+1,26);
$T[1]=substr($x,$i+30,$j-$i-30);
push(@T,split(/ /,substr($x,0,$i-1).substr($x,$j+1)));
#----------------------------------------------------------------------------
$timestamp=str2time($T[0]);
$request=$T[1];
$host=unpack("N",pack("C4",split(/\./,$T[2])));
}
8X----------------