Zdobądźmy trochę danych na ten temat. I na podstawie porównania technik niesłyszących ...
#!/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); },
};
Ponieważ jest I/O, które mogą mieć wpływ sił poza zdolnością Benchmark.pm dostosowania do pobiegłem do nich kilka razy i sprawdzone mam takie same wyniki.
/usr/share/dict/words
to plik o rozdzielczości 2,4 megapiksela z bardzo krótkimi liniami o długości 240k. Ponieważ nie przetwarzamy linii, długość linii nie powinna mieć znaczenia.
Zrobiłem tylko niewielką ilość pracy w każdej rutynie, aby podkreślić różnicę między technikami. Chciałem wykonać pewną pracę w celu uzyskania realistycznego górnego limitu wydajności, którą zamierzasz uzyskać lub stracić zmieniając sposób czytania plików.
Zrobiłem to na laptopie z dyskiem SSD, ale nadal jest to laptop. Wraz ze wzrostem prędkości we/wy czas procesora staje się coraz ważniejszy. Technika jest jeszcze ważniejsza na maszynie z szybkimi wejściami i wyjściami.
Oto, ile razy każda rutyna odczytuje plik na sekundę.
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
jestem wstrząśnięci, że my @array = <$fh>
jest najwolniejsze przez ogromny margines. Pomyślałbym, że będzie to najszybsze, biorąc pod uwagę, że cała praca dzieje się wewnątrz interpretera perla. Jednak to jedyny, który przydziela pamięć do przechowywania wszystkich linii i prawdopodobnie odpowiada za opóźnienie wydajności.
Używanie $.
to kolejna niespodzianka.Być może to jest koszt dostępu do magii globalnej, a może jej porównanie liczbowe.
I, zgodnie z przewidywaniami analizy algorytmicznej, umieszczenie kodu sprawdzania nagłówka poza pętlą jest najszybsze. Ale nie za dużo. Prawdopodobnie nie wystarczy, aby się martwić, jeśli używasz dwóch kolejnych najszybszych.
Jako marginesie, plasterki tablicy i dołącz wyeliminuje wiele tego powtarzającego się kodu. 'print OUTFILE" $ columns [0] \ t \ t "; print OUTFILE join ("\ t", @kolumny [1,2,3,11,12,15,20,21]); print OUTFILE "\ n"; ' – Schwern
Będę musiał sprawdzić dołączenie. Jestem nowy w Perlu. Dzięki! – New2Perl
Oczyściłem to jeszcze bardziej: 'print OUTFILE" $ columns [0] \ t \ t ". join ("\ t", @columns [1,2,3,11,12,15,20,21]). "\ n"; ' – New2Perl