优化Perl脚本以处理大量数据

优化Perl脚本以处理大量数据,perl,Perl,这是我的剧本: #!/usr/bin/perl -w use warnings; use strict; no warnings 'uninitialized'; `rm /slot/ems12093/oracle/working/marchfound.txt`; `touch /slot/ems12093/oracle/working/marchfound.txt`; `rm /slot/ems12093/oracle/working/newcontact.txt`; `touch /s

这是我的剧本:

#!/usr/bin/perl -w

use warnings;
use strict;
no warnings 'uninitialized';

`rm /slot/ems12093/oracle/working/marchfound.txt`;
`touch /slot/ems12093/oracle/working/marchfound.txt`;

`rm /slot/ems12093/oracle/working/newcontact.txt`;
`touch /slot/ems12093/oracle/working/newcontact.txt`;

my ( $filename, $handle, @contact_list, $file_list, $k, @file_list2, $i, $e, $m, $fh, $f, $g,
    $file1, $data, $file_location, $arrSize, $namefile );

$file_location = '/slot/ems12093/oracle/working/marchfound.txt';
$filename      = '/slot/ems12093/oracle/working/contact.txt';

open( $handle, '<', $filename ) or die $!;
@contact_list = <$handle>;
close $handle;

chomp @contact_list;

chdir( '/scratch/mount_point/dnbfiles/oracle_cr/' );
$file_list = qx(ls|grep -i \"2016_03_Mar_EA\");
chomp( $file_list );

$k = "/scratch/mount_point/dnbfiles/oracle_cr/2016_03_Mar_EA";
chdir( $k );

@file_list2 = qx(ls|grep -i contact|grep -i full|grep -Ev "Glb");
chomp @file_list2;

foreach $file1 ( @file_list2 ) {

    foreach $i ( @contact_list ) {

        $e = "zgrep $i $file1";
        $f = qx($e);

        if ( $f ) {
            print "working\n";

            $g = "$f, $file1";

            open $data, '>>', $file_location or die $!;
            print $data "$g\n";
            close $data;

            @contact_list = grep { !/$i/ } @contact_list;
            $arrSize = @contact_list;
            print "$arrSize\n";
        }
    }

}

$m = "/slot/ems12093/oracle/working/";
chdir( $m );

chomp @contact_list;
$namefile = '/slot/ems12093/oracle/working/newcontact.txt';
open( $fh, '<', $namefile ) or die $!;
@contact_list = <$fh>;
close $fh;

print "done\n";
#/usr/bin/perl-w
使用警告;
严格使用;
没有“未初始化”的警告;
`rm/slot/ems12093/oracle/working/marchfound.txt`;
`touch/slot/ems12093/oracle/working/marchfound.txt`;
`rm/slot/ems12093/oracle/working/newcontact.txt`;
`touch/slot/ems12093/oracle/working/newcontact.txt`;
我的($filename,$handle,@contact\u list,$file\u list,$k,@file\u list2,$i,$e,$m,$fh,$f,$g,
$file1、$data、$file\u location、$arrSize、$namefile);
$file_location='/slot/ems12093/oracle/working/marchfound.txt';
$filename='/slot/ems12093/oracle/working/contact.txt';
打开($handle,“>”,$file_location或die$!;
打印$data“$g\n”;
关闭$数据;
@contact_list=grep{!/$i/}@contact_list;
$arrSize=@联系人列表;
打印“$arrSize\n”;
}
}
}
$m=“/slot/ems12093/oracle/working/”;
chdir(百万美元);
chomp@contact_list;
$namefile='/slot/ems12093/oracle/working/newcontact.txt';

open($fh,不完全是速度特定的,但您应该做以下修改

1) contact.txt有370k条记录,所以你不应该一次就把整个数据都弄脏了。所以不要这样做

@contact_list = <$handle>;
  • 按照您这样做的方式,我敢打赌大部分时间都花在压缩数据库转储上(这将发生370k次)。在进行匹配之前先解压缩一次(假设您有足够的磁盘)
  • 如果您不检查实际的regexp,fgrep将节省一些(边际)时间(尽管我怀疑这个优化是由grep在内部完成的)
  • 建议不要对文件进行slurping,这有助于节省内存,并且对于数据的单次扫描不会对速度产生太大影响。但是,实际上,为了消除重复的联系人,您正在不必要地对arry进行多次扫描

    @contact_list=grep{!/$i/}@contact_list

  • 这并不总是会减慢整个shebang的速度,它还浪费了内存,因为@contact_列表被复制到内存中

    您可以按行读取,在哈希中保持跟踪,并跳过重复的循环体:

    next if exists $seen{$i};
    $seen{$i}++
    

    如果不使用一个字母的变量名,而是使用描述性名称,则更容易理解您试图执行的操作。请使用更好的变量重写您的问题,以便我们跟进。不要为此使用数组:
    @contact_list=;
    ,像这样使用while循环
    while(my$contact_row=){chomp($contact_row);do_stuff;}
    关闭$handle;并按照@xxfelixxx说明操作。
    -w
    使用警告
    做的事情基本相同。如果您有
    使用警告
    ,则不需要
    -w
    。当您想要捕获外部命令的输出时,会使用反勾号。您可能需要使用
    系统()
    相反(但也可以使用Perl自己的
    unlink()
    函数,而不是调用外部程序)
    或File::Find将比直接搜索
    ls
    grep
    效率更高。我投票将此问题作为离题问题结束,因为此问题更适合于。您不会针对特定问题提出特定问题。
    my @files = File::Find::Rule->file()->name( '*.pm' )->in( @INC );
    
    next if exists $seen{$i};
    $seen{$i}++