Я создаю подпрограмму, которая:
(1) Разбирает CSV файл,
(2) И проверяет, имеют ли все строки в этом файле ожидаемое количество столбцов. Он кричит, если количество столбцов недействительно.
Когда число строк колеблется от тысяч до миллионов, , как вы думаете, это самый эффективный способ сделать это?
Сейчас я пытаюсь выполнить эти реализации.
(1) Базовый парсер файлов
open my $in_fh, '<', $file or
croak "Cannot open '$file': $OS_ERROR";
my $row_no = 0;
while ( my $row = <$in_fh> ) {
my @values = split (q{,}, $row);
++$row_no;
if ( scalar @values < $min_cols_no ) {
croak "Invalid file format. File '$file' does not have '$min_cols_no' columns in line '$row_no'.";
}
}
close $in_fh
or croak "Cannot close '$file': $OS_ERROR";
(2) Использование Text:: CSV_XS (bind_columns и csv- > getline)
my $csv = Text::CSV_XS->new () or
croak "Cannot use CSV: " . Text::CSV_XS->error_diag();
open my $in_fh, '<', $file or
croak "Cannot open '$file': $OS_ERROR";
my $row_no = 1;
my @cols = @{$csv->getline($in_fh)};
my $row = {};
$csv->bind_columns (\@{$row}{@cols});
while ($csv->getline ($in_fh)) {
++$row_no;
if ( scalar keys %$row < $min_cols_no ) {
croak "Invalid file format. File '$file' does not have '$min_cols_no' columns in line '$row_no'.";
}
}
$csv->eof or $csv->error_diag();
close $in_fh or
croak "Cannot close '$file': $OS_ERROR";
(3) Использование Text:: CSV_XS (csv- > parse)
my $csv = Text::CSV_XS->new() or
croak "Cannot use CSV: " . Text::CSV_XS->error_diag();
open my $in_fh, '<', $file or
croak "Cannot open '$file': $OS_ERROR";
my $row_no = 0;
while ( <$in_fh> ) {
$csv->parse($_);
++$row_no;
if ( scalar $csv->fields < $min_cols_no ) {
croak "Invalid file format. File '$file' does not have '$min_cols_no' columns in line '$row_no'.";
}
}
$csv->eof or $csv->error_diag();
close $in_fh or
croak "Cannot close '$file': $OS_ERROR";
(4) Использование Parse:: CSV
use Parse::CSV;
my $simple = Parse::CSV->new(
file => $file
);
my $row_no = 0;
while ( my $array_ref = $simple->fetch ) {
++$row_no;
if ( scalar @$array_ref < $min_cols_no ) {
croak "Invalid file format. File '$file' does not have '$min_cols_no' columns in line '$row_no'.";
}
}
Я сравнивал их с помощью модуля Benchmark.
use Benchmark qw(timeit timestr timediff :hireswallclock);
И это числа (в секундах), которые я получил:
1000 строк файла:
Реализация 1: 0,0016
Реализация 2: 0,0025
Реализация 3: 0.0050
Реализация 4: 0,0097
10 000 строк файла:
Реализация 1: 0.0204
Реализация 2: 0.0244
Реализация 3: 0,0523
Реализация 4: 0.1050
150000 строк файла:
Реализация 1:1.8697
Реализация 2: 3.1913
Реализация 3: 7.8475
Реализация 4: 15.6274
Учитывая эти числа, я бы сделал вывод, что простой парсер является самым быстрым, но из того, что я читал из разных источников, Text:: CSV_XS должен быть самым быстрым.
Кто-нибудь просветит меня по этому поводу? Что-то не так с тем, как я использовал модули? Большое спасибо за вашу помощь!