【发布时间】:2014-05-09 12:39:02
【问题描述】:
我在这里需要速度。我有一个 500mb 大小的 csv 文件(实际上有很多 csv 但我现在只考虑一个) 我需要阅读第 3 列并从中选择唯一的字符串。以下方法我测试过,我发现只有 awk 是最快的
使用 perl:
- 使用传统方式读取文件打开文件并通过 while 循环的文件句柄
- 取消设置 $/ 变量并将整个文件转换为字符串,然后 分割线并选择第三个字段并继续
- 使用 File::Slurp 模块
- 使用 Text::CSV / XS 读取 csv 并做必要的事情
在上述所有方式中,解析 csv 大约需要 500 秒。
但如果我尝试使用 awk 执行相同操作,它会在将近 10 秒内完成。
我仍在学习 perl 的步骤,最近在看到它的哈希功能后,我对它的热情越来越高。但是这个问题困扰了我 背部。这是 unix 工具占上风的 perl 的一些限制吗?
我知道 Text::CSV 是处理 csv 文件的最佳方式。但是速度是我关心的问题,我可以保证我的 csv 没有任何嵌入的逗号或其他只有 Text::CSV 处理的问题。
更新:发现我的问题
my %hash;
my $file = $ARGV[0] or die "Need input CSV $!\n";
open(my $fh,'<',$file) or die "Could not open the $file $!\n";
while(my $line = <$fh>)
{
chomp($line);
my $field2=(split /|/, $line)[2]; #I missed to quote the pipe delimiter
$hash{$field2}++;
}
print "$_\n" for keys %hash;
另一个更新:问题和修复
我的 csv 由“|”分隔我错过了引用它们。因此,执行时间显着减慢,而且它产生的输出是错误的,我没有注意到。引用分隔符后,脚本能够在大约 18 秒内完成,当我使用 @Borodin 限制字段拆分的逻辑时,执行时间进一步减少。我能够达到与 awk 相同的速度。
我仍然发现 Text::CSV 方法较慢,因为我的文件可以使用默认的拆分方法,所以我将使用它。
【问题讨论】:
-
向我们展示代码和一些示例输入行。
-
啜饮一个 500 MiB 的文件不是一个好主意。每行有多宽(500 MiB 文件中有多少行)?多少个领域?您如何收集第三列?一旦你收集了它,你会用它做什么?您是否在“awk”模式下尝试过 Perl (
perl -n -a -F, -l -e 'print $F[2]')? -
Text::CSV_XS 是纯C;它可能会加快你的代码速度。
-
cut -d '|' -f 3 | sort -u是怎么做的,如果这就是你所需要的? -
是的,cut/awk + sort 从一开始就很好。我只是想知道为什么 perl 很慢。现在我很高兴我找到了问题和解决方案