【问题标题】:how to speed up the grep speed of this Perl script如何加快这个 Perl 脚本的 grep 速度
【发布时间】:2015-01-20 20:18:10
【问题描述】:

目前我有一个需要提取日志的脚本。下面是 Perl 代码 sn-p: 脚本遍历每个服务器文件夹并 grep 必要的信息。问题是当日志数量可能很大时,脚本可能需要很长时间才能完成。瓶颈是这条线:

@leaf_lines = qx($grep -l "stagename = $current_stage" $grep_path| xargs $grep "Keywords")

我想知道是否有任何方法可以加快此操作? 脚本运行在每个 CPU 8 核和 8G 内存的服务器上,有没有办法使用这些资源?

my $grep = ($leaflog_zipped) ? "zgrep" : "grep" ;
my %leaf_info;
my @stage = ("STAGE1", "STAGE1", "STAGE3");
foreach my $leaf_dir (@leaf_dir_list){
    my $grep_path = $log_root_dir . "/$leaf_dir/*" ;          
    foreach my $current_stage (@stage){
        my @leaf_lines;
        @leaf_lines = qx($grep -l "stagename = $current_stage" $grep_path| xargs $grep "Keywords"); ## how to improve the grep speed?  
        foreach (@leaf_lines){
            if(...){
                $leaf_info{$current_stage}{xxx} = xxxx;
            }
        }    
    }
}

【问题讨论】:

    标签: bash perl grep


    【解决方案1】:

    对于初学者-我想说不要'shell out'到 grep-perl 具有非常好的内置模式匹配和正则表达式,并且包括预编译正则表达式的能力。

    http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators

    另外 - 您可以使用线程或分叉相当轻松地并行运行 perl,这可以更好地利用您的 CPU 资源。

    但是我要指出 - 像 grep 这样的东西通常不是与 CPU 相关的问题。这些天 CPU 非常快,而文件系统通常要慢得多。你可能会花费更多的时间从磁盘读取数据,而不是处理它,这在很大程度上是一个很大的差距。

    因此,可能会给您带来很多悲伤的事情是您多次 grep。

    my $grep_path = $log_root_dir . "/$leaf_dir/*" ;          
    foreach my $current_stage (@stage)
    

    @stage 的每个元素都会触发另一个 grep,它会针对该目录中的每个文件执行此操作。然后你又再次 grepping。

    这是一个糟糕的算法,因为您将多次读取每个文件。为什么不这样做:

    #could do this with map - I haven't for clarity. 
    my %stages;
    $stages{'STAGE1'}++;
    $stages{'STAGE2'}++;
    $stages{'STAGE3'}++;
    
    foreach my $file ( glob $grep_path ) {
        open( my $input_fh, "<", $file ) or die $!;
        while (<$input_fh>) {
            if (m/current_stage/) {
                my ($file_stage) = (
                    m/stagename = (\w+)/;
                );
                if ( $stages{$file_stage} ) {
                    # do something here
                }
            }
        }
    }
    

    这样 - 虽然您必须阅读每个文件 - 您只需要这样做一次。

    【讨论】:

      【解决方案2】:

      是的,当然。只需将 xargs 替换为 GNU Parallel 或其他类似程序即可(在某些 Linux 系统上有多个名为 parallel 的程序,因此请注意您拥有的程序;GNU Parallel 可能是最好的)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-28
        • 2012-08-23
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 2014-10-16
        • 2015-09-23
        相关资源
        最近更新 更多