次のようなサブルーチンを作成しています。
(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->解析)
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'.";
}
}
ベンチマークモジュールを使用してベンチマークを行いました。
use Benchmark qw(timeit timestr timediff :hireswallclock);
そして、これらは私が得た数(秒単位)です:
1,000行のファイル:
実装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
1,500,000行のファイル:
実装1:1.8697
実装2:3.1913
実装3:7.8475
実装4:15.6274
これらの数値を考慮すると、単純なパーサーが最速であると結論付けますが、さまざまなソースから読み取ったものから、Text::CSV_XSが最速であるはずです。
誰かがこれについて私に教えてくれますか?モジュールの使用方法に問題がありますか?あなたの助けをどうもありがとう!