Performance 为什么我的perl代码的执行时间变化如此之大?

Performance 为什么我的perl代码的执行时间变化如此之大?,performance,perl,Performance,Perl,我发现下面的perl代码执行速度惊人地变化,有时快,有时慢。我有几个文件夹,其中包含数以万计的文件,我需要运行这些代码。我用Windows7在cygwin上运行这个。只是想知道是否有人能帮我加快速度,或者至少能找出速度变化的原因。在所有这些情况下,我的CPU和内存都应该充足 在$dir的列表中迭代的外部循环 opendir(DIR, $dir); @all=readdir(DIR); @files = (0..$#all); $i=-1; foreach $current (@all){

我发现下面的perl代码执行速度惊人地变化,有时快,有时慢。我有几个文件夹,其中包含数以万计的文件,我需要运行这些代码。我用Windows7在cygwin上运行这个。只是想知道是否有人能帮我加快速度,或者至少能找出速度变化的原因。在所有这些情况下,我的CPU和内存都应该充足

在$dir的列表中迭代的外部循环

opendir(DIR, $dir);
@all=readdir(DIR);
@files = (0..$#all);
$i=-1;
foreach $current (@all){     
    if (-f "$dir/$current") {
        $files[++$i]=$current;
    }
}
push @Allfiles,@files[0..$i];
closedir(DIR);

如果第一次运行时速度很慢,之后又很快,那么问题是系统正在缓存读取。第一次运行代码时,必须从磁盘读取数据。之后,数据仍然缓存在RAM中。如果您等待的时间足够长,缓存将刷新,您将不得不再次访问磁盘


或者,有时您可能会同时运行一些其他磁盘密集型任务,但在运行代码的其他时间不会这样做。

如果第一次运行时速度很慢,之后又很快,则问题在于系统正在缓存读取。第一次运行代码时,必须从磁盘读取数据。之后,数据仍然缓存在RAM中。如果您等待的时间足够长,缓存将刷新,您将不得不再次访问磁盘


或者,有时您可能同时运行一些其他磁盘密集型任务,但在运行代码的其他时间不会运行。

您可能受到I/O限制,因此对代码的更改可能不会影响总运行时间-运行时间将受目录项是否在缓存中的影响

但是您的代码使用临时数组并没有什么好的理由,如果目录非常大,就会使用太多的RAM。您可以将其简化为:

opendir(DIR, $dir);
while (my file = readdir(DIR)) {
    push @Allfiles, $file if (-f "$dir/$file");
}
closedir(DIR);

没有临时数组。

您可能受I/O限制,因此对代码的更改可能不会影响整个运行时-运行时将受到目录项是否在缓存中的影响

但是您的代码使用临时数组并没有什么好的理由,如果目录非常大,就会使用太多的RAM。您可以将其简化为:

opendir(DIR, $dir);
while (my file = readdir(DIR)) {
    push @Allfiles, $file if (-f "$dir/$file");
}
closedir(DIR);


没有临时阵列。

您是否同时在计算机上执行其他操作,如运行bittorrent或游戏服务器或类似程序?您是否同时在计算机上执行其他操作,如运行bittorrent或游戏服务器或类似程序?如果OP内存严重受限,则这些临时阵列可能会向下交换到磁盘,大大降低了速度(讽刺的是)。如果没有考虑到这一点,那么必须是非常大的目录或非常紧张的内存。在这种情况下,删除临时文件会有所帮助,但在这种情况下,
@Allfiles
本身可能会变得太大。。。我想,在这种情况下,除了分解工作之外,没有真正的解决方案。您需要在while()条件中实际分配给$\u0,因为readdir()不是为您将内容放入$\u0的特例。@tadmc:在发布它之前,我已经测试过了,它已经工作了(我想是perl 5.12)。但事实上,我这里介绍的Perl5.8并没有这样做。。。或者可能当时我没有喝足够的咖啡,想象着整个事情:-/修复了,谢谢。我一开始就尝试了这个代码。相当慢。然后我想可能是名单上的推慢了事情的发展。因此,我首先尝试分配一个足够长的数组。因此,在您看来,list的推送或移位不应该是导致速度慢的罪魁祸首?如果OP内存严重受限,那么这些临时阵列可能会切换到磁盘,从而大大降低速度(具有讽刺意味的是)。如果没有想到这一点,那么必须是非常大的目录或非常紧张的内存。在这种情况下,删除临时文件会有所帮助,但在这种情况下,
@Allfiles
本身可能会变得太大。。。我想,在这种情况下,除了分解工作之外,没有真正的解决方案。您需要在while()条件中实际分配给$\u0,因为readdir()不是为您将内容放入$\u0的特例。@tadmc:在发布它之前,我已经测试过了,它已经工作了(我想是perl 5.12)。但事实上,我这里介绍的Perl5.8并没有这样做。。。或者可能当时我没有喝足够的咖啡,想象着整个事情:-/修复了,谢谢。我一开始就尝试了这个代码。相当慢。然后我想可能是名单上的推慢了事情的发展。因此,我首先尝试分配一个足够长的数组。所以在你看来,列表的推动或移动,就这一点而言,不应该是速度慢的罪魁祸首?它第一次是慢的,其他一些非第一次也是慢的。我有8GB的内存,这不足以将文件保存在缓存中吗?顺便说一句,当我观察到这一点时,我并没有同时运行其他磁盘密集型任务。您是否运行内存密集型的任务,比如Firefox上有大量的视频标签?8GB应该足够了,除非您列出的目录中满是小文件(小于4k)。不,对于那些内存密集型任务,根本没有。这就是为什么我很想知道为什么跑步之间会有差异。第一次跑得很慢,其他一些非第一次跑得也很慢。我有8GB的内存,这不足以将文件保存在缓存中吗?顺便说一句,当我观察到这一点时,我并没有同时运行其他磁盘密集型任务。您是否运行内存密集型的任务,比如Firefox上有大量的视频标签?8GB应该足够了,除非您列出的目录中满是小文件(小于4k)。不,对于那些内存密集型任务,根本没有。这就是为什么我很想知道为什么跑步之间存在差异。