Linux 如何解决在一台服务器上运行速度快但在另一台服务器上运行速度慢的非常慢的perl脚本的故障

Linux 如何解决在一台服务器上运行速度快但在另一台服务器上运行速度慢的非常慢的perl脚本的故障,linux,performance,perl,Linux,Performance,Perl,我收到了一个perl脚本,该脚本应该用于过滤Hi-C数据的探测,但它运行得很慢(几天)。给我脚本的那个人告诉我,在她以前实验室的服务器上只花了几个小时,所以我想知道是什么导致运行时间如此不同,我该如何让它运行得更快?我对perl的了解非常有限,但我的google搜索结果表明我可能需要更改一些perl配置文件?下面是整个脚本中花费时间最长的主要函数,输入文件包含染色体目标和位置。任何帮助都将不胜感激 我试着用Perl5.16和5.26运行,看看这个版本是否太旧了,但也花了同样长的时间 sub ge

我收到了一个perl脚本,该脚本应该用于过滤Hi-C数据的探测,但它运行得很慢(几天)。给我脚本的那个人告诉我,在她以前实验室的服务器上只花了几个小时,所以我想知道是什么导致运行时间如此不同,我该如何让它运行得更快?我对perl的了解非常有限,但我的google搜索结果表明我可能需要更改一些perl配置文件?下面是整个脚本中花费时间最长的主要函数,输入文件包含染色体目标和位置。任何帮助都将不胜感激

我试着用Perl5.16和5.26运行,看看这个版本是否太旧了,但也花了同样长的时间

sub get_restriction_fragments_for_targets {

    my @targets = @_;

    # Split by chromsome and sort
    my %targets;

    foreach my $target (@targets) {
            push @{$targets{$target->{chr}}},$target;
    }

    foreach my $chr (keys %targets) {
            my @sorted = sort {$a -> {start} <=> $b -> {start}} @{$targets{$chr}};

            # We also need to merge overlapping capture regions

            my @merged;

            my $last_region;

            foreach my $region (@sorted) {
                    unless ($last_region) {
                            $last_region = $region;
                            next;
                    }

                    if ($region->{start} < $last_region -> {end}) {
                            # Merge
                            if ($region ->{end} > $last_region->{end}) {
                                    $last_region->{end} = $region->{end};
                            }
                            next;
                    }

                    push @merged,$last_region;
                    $last_region = $region;
            }

            push @merged,$last_region;

            $targets{$chr} = \@merged;
    }

    my @target_fragments;

    open (IN,'all_restriction_fragments.txt') or die $!;

    my $last_chr = "";
    my $last_index = 0;

    while (<IN>) {
            chomp;
            my $line = $_;

            my ($chr,$start,$end) = split(/\t/);

            if ($chr ne $last_chr) {
                    warn "Moving to $chr\n";
                    $last_chr = $chr;
                    $last_index = 0;
            }

            next unless (exists $targets{$chr});

            my @local_targets = @{$targets{$chr}};

            foreach my $index ($last_index .. $#local_targets) {
                    my $target = $local_targets[$index];

                    if ($target -> {end} < $start) {
                            $last_index = $index;
                            next;
                    }

                    if ($target -> {start} > $end) {
                            last;
                    }

                    push @target_fragments,{
                            id => $target->{id},
                            chr => $chr,
                            start => $start,
                            end => $end,
                    };
                    last;
            }
    }

    return @target_fragments;
}
sub-get\u-restriction\u-fragments\u用于\u目标{
我的@targets=@;
#按色度和排序分割
我的%目标;
foreach我的$target(@targets){
push@{$targets{$target->{chr}}},$target;
}
foreach my$chr(关键字%targets){
my@sorted=sort{$a->{start}$b->{start}}}{$targets{$chr};
#我们还需要合并重叠的捕获区域
我的@merge;
我的$last_区域;
foreach my$区域(@sorted){
除非($last_地区){
$last_region=$region;
下一个
}
如果($region->{start}<$last_region->{end}){
#合并
如果($region->{end}>$last_region->{end}){
$last_region->{end}=$region->{end};
}
下一个
}
推送@merged$last_区域;
$last_region=$region;
}
推送@merged$last_区域;
$targets{$chr}=\@合并;
}
我的@target_片段;
打开(在“all_restriction_fragments.txt”中)或死亡$!;
我的$last_chr=“”;
我的$last_索引=0;
而(){
咀嚼;
我的$line=$\ux;
my($chr,$start,$end)=拆分(/\t/);
如果($chr ne$last_chr){
警告“移动到$chr\n”;
$last_chr=$chr;
$last_index=0;
}
下一个除非(存在$targets{$chr});
my@local_targets=@{$targets{$chr};
foreach my$索引($last_index..$#local_targets){
my$target=$local_targets[$index];
如果($target->{end}<$start){
$last_index=$index;
下一个
}
如果($target->{start}>$end){
最后;
}
推送@target_碎片{
id=>$target->{id},
chr=>$chr,
start=>$start,
end=>end美元,
};
最后;
}
}
返回@target_碎片;
}

如果不知道更多关于这个问题的信息,首先是关于数据结构的大小和处理的文件的大小,就无法判断问题

下面是一个一般性的注释,说明在代码似乎正在执行的操作中,原则上最耗时的操作是什么(可能是)重要性和/或可能性递减的顺序

  • 档案有多大?这是磁盘访问,可能需要任何时间

  • 循环排序——正在排序的数据有多大?
    排序
    非常耗时

  • 有一种“踢踏舞”围绕着排序的@sorted,这会导致数据拷贝——有多少数据

  • 一般来说,有大量的数据复制——传递到例程中的
    @targets
    有多大

如您所见,每个因素都伴随着数据有多大的问题。磁盘访问当然成本很高,但在程序中的各种数据结构之间复制大量数据也同样重要


因此,如果您能提供一些详细信息,我们将帮助您进行更详细的分析/猜测。

您是否对两台服务器中涉及的硬件、正在使用的磁盘系统以及配置方式进行了简要比较?脚本运行的天数听起来像是某种或多种硬件问题。祝你好运。不要猜测:使用Devel::NYTProf运行脚本并发现时间花在了哪里。由于运行时间是完全不可接受的,特别是出于测试目的,所以一定要针对较小的数据集运行。