Prendiamo alcuni dati su questo. I benchmark tecniche di tutti ...
#!/usr/bin/env perl
sub flag_in_loop {
my $file = shift;
open my $fh, $file;
my $first = 1;
while(<$fh>) {
if($first) {
$first = 0;
}
else {
my $line = $_;
}
}
return;
}
sub strip_before_loop {
my $file = shift;
open my $fh, $file;
my $header = <$fh>;
while(<$fh>) {
my $line = $_;
}
return;
}
sub line_number_in_loop {
my $file = shift;
open my $fh, $file;
while(<$fh>) {
next if $. < 2;
my $line = $_;
}
return;
}
sub inc_in_loop {
my $file = shift;
open my $fh, $file;
my $first;
while(<$fh>) {
$first++ or next;
my $line = $_;
}
return;
}
sub slurp_to_array {
my $file = shift;
open my $fh, $file;
my @array = <$fh>;
shift @array;
return;
}
my $Test_File = "/usr/share/dict/words";
print `wc $Test_File`;
use Benchmark;
timethese shift || -10, {
flag_in_loop => sub { flag_in_loop($Test_File); },
strip_before_loop => sub { strip_before_loop($Test_File); },
line_number_in_loop => sub { line_number_in_loop($Test_File); },
inc_in_loop => sub { inc_in_loop($Test_File); },
slurp_to_array => sub { slurp_to_array($Test_File); },
};
Poiché si tratta di I/O che può essere influenzato da forze al di là della capacità di Benchmark.pm per regolare, mi sono imbattuto più volte ed ho controllato ho ottenuto gli stessi risultati.
/usr/share/dict/words
è un file da 2,4 megapixel con circa 240 k linee molto brevi. Poiché non stiamo elaborando le linee, la lunghezza della linea non dovrebbe avere importanza.
Ho fatto solo una piccola quantità di lavoro in ciascuna routine per enfatizzare la differenza tra le tecniche. Volevo fare un po 'di in modo da produrre un limite superiore realistico su quanto prestazioni andresti a guadagnare o perdere cambiando il modo in cui leggi i file.
L'ho fatto su un laptop con un SSD, ma è ancora un laptop. Con l'aumentare della velocità di I/O, il tempo della CPU diventa più significativo. La tecnica è ancora più importante su una macchina con I/O veloce.
Ecco quante volte ogni routine legge il file al secondo.
slurp_to_array: 4.5/s
line_number_in_loop: 13.0/s
inc_in_loop: 15.5/s
flag_in_loop: 15.8/s
strip_before_loop: 19.9/s
Sono scioccato di scoprire che my @array = <$fh>
è il più lento con un margine enorme. Avrei pensato che sarebbe stato il più veloce dato che tutto il lavoro sta accadendo all'interno dell'interprete perl. Tuttavia, è l'unico che alloca la memoria per contenere tutte le linee e che probabilmente rappresenta il ritardo delle prestazioni.
L'utilizzo di $.
è un'altra sorpresa.Forse è il costo di accedere a una magia globale, o forse sta facendo un confronto numerico.
E, come previsto dall'analisi algoritmica, il codice di controllo dell'intestazione all'esterno del ciclo è il più veloce. Ma non di molto. Probabilmente non abbastanza da preoccuparti se stai usando i prossimi due tempi.
Come nota a margine, le fette di array e unisciti eliminerebbe un sacco di quel codice ripetuto. 'print OUTFILE" $ columns [0] \ t \ t "; stampa join OUTFILE ("\ t", @columns [1,2,3,11,12,15,20,21]); print OUTFILE "\ n"; ' – Schwern
Dovrò cercare di entrare. Sono nuovo di Perl. Grazie! – New2Perl
Ripulito un po 'di più: 'print OUTFILE" $ columns [0] \ t \ t ". join ("\ t", @columns [1,2,3,11,12,15,20,21]). "\ n"; ' – New2Perl