【问题标题】:Parsing multiple files at a time in Perl在 Perl 中一次解析多个文件
【发布时间】:2011-06-02 00:25:45
【问题描述】:

我有一个大型数据集(大约 90GB)可以使用。每天每个小时都有数据文件(制表符分隔),我需要在整个数据集中执行操作。例如,获取其中一列中给出的操作系统的份额。我尝试将所有文​​件合并到一个大文件中并执行简单的计数操作,但它对于服务器内存来说太大了。

所以,我想我需要一次执行每个文件的操作,然后最后加起来。我是 perl 的新手,对性能问题特别天真。这种情况下怎么做这样的操作。

例如,文件的两列是。

ID      OS
1       Windows
2       Linux
3       Windows
4       Windows

让我们做一些简单的事情,计算数据集中操作系统的份额。因此,每个 .txt 文件都有数百万行这样的文件,并且有很多这样的文件。对整个文件进行操作的最有效方法是什么。

【问题讨论】:

    标签: perl performance parsing file memory-management


    【解决方案1】:

    除非您将整个文件读入内存,否则我不明白为什么文件的大小会成为问题。

    my %osHash;
    
    while (<>)
    {
       my ($id, $os) = split("\t", $_);
       if (!exists($osHash{$os}))
       {
          $osHash{$os} = 0;
       }
       $osHash{$os}++;
    }
    
    foreach my $key (sort(keys(%osHash)))
    {
       print "$key : ", $osHash{$key}, "\n";
    }
    

    【讨论】:

    • 你不必在增加值之前检查key是否存在;如果它还不存在,它将在现场创建。
    • @canavanin,它会被初始化为零吗?我从来没有测试过。
    • 排序键中也不需要父母 %osHash;或者在拆分中使用 $_ ,因为它默认使用它; Camelcase 也让 Perlers 的一个相当大的子集感到畏缩,所以你可能想避免这种情况。
    • @Hugmeir:我建议将“parens”作为“括号”的缩写,因为“父母”在英语中(即使在计算方面)是一个非常好的词,具有完全不同的含义。
    • 是 - 密钥初始化为零;它也不会在 warnings 或 strict 下触发任何警告。
    【解决方案2】:

    虽然 Paul Tomblin 的回答涉及填充哈希,但这里是相同的以及打开文件:

    use strict;
    use warnings;
    use 5.010;
    use autodie;
    
    my @files = map { "file$_.txt" } 1..10;
    
    my %os_count;
    
    for my $file (@files) {
        open my $fh, '<', $file;
        while (<$file>) {
            my ($id, $os) = split /\t/;
            ... #Do something with %os_count and $id/$os here.
        }
    }
    

    我们只是依次打开每个文件——因为您需要从所有文件中读取所有行,所以您无能为力。获得哈希后,您可以将其存储在某处并在程序启动时加载它,然后跳过所有行直到您阅读的最后一行,或者只是 seek 那里,如果您的记录预先确定,这看起来不像。

    【讨论】:

    • 如果我错了,请纠正我,但是如果您在命令行上传递文件名, 是否可以访问它们,或者只有在您重定向标准输入时才可以访问它们?
    • 你是对的。您的解决方案完美运行(除非您想要编码,但是嗯),甚至为您自动进行错误检查,我的解决方案必须通过 autodie - 我只是更明确地展示它。它的可扩展性也略高一些,因为它可能会出现在前卫的中间,而其他东西已经破坏了 ARGV。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 2016-01-22
    • 2012-06-08
    • 1970-01-01
    相关资源
    最近更新 更多