与并行运行一样,更快地完成此脚本的最佳解决方案是什么?
#!usr/bin/perl
use warnings;
use strict;
use threads;
open(R1 ,"<$ARGV[0]") || die " problem in oppening $ARGV[0]: $!\n";
my %dict1 : shared;
my $i=0;
while (my $l = <R1>){
chomp($l);
$l=~ s/\s$//;
$l=~ s/^\s//;
if ($l=~ /(.*)\s(.*)/){
$i++;
#print $1,"\n";
#my $t = threads->create($dict1{$1}++);
$dict1{$1}++;
}
}
print $i, "\n";
close R1;
答案 0 :(得分:1)
您可以创建与文件的相等部分对应的$N
元素数组
my $N = 6;
my $step = int( $file_size/$N );
my @arr = map { ($_-1) * $step } 1 .. $N;
然后通过寻找文件位置(perldoc -f seek
),读取行的其余部分(perldoc -f readline
)并告知更正的文件位置(perldoc -f tell
)来更正这些数字。
启动$N
个线程,其中每个线程已经知道从哪里开始提取作业,并在最后加入他们的结果。然而,你可能会发现,媒体阅读是实际的瓶颈,正如@ikegami已经指出的那样。
答案 1 :(得分:0)
最可能的情况是,您受到从磁盘读取数据的速度(“I / O界限”)的限制,而不受处理时间(“CPU绑定”)的限制。如果是这种情况,那么你可以用线程或并行执行 nothing 来加快速度 - 如果它有任何影响,并行化会通过强制磁盘跳回来减慢你的速度在不同进程/线程读取的文件各部分之间。
测试是否是这种情况的简单方法是打开shell并运行命令cat my_data_file > /dev/null
这应该告诉您从磁盘读取文件需要多长时间,而不实际做任何事情。如果它与在my_data_file
上运行程序所需的时间大致相同,那么就不要费心去尝试优化或加速它了。你不能。在这种情况下,只有两种方法可以提高性能:
更改代码的工作方式,以便您无需读取整个文件。如果您正在处理将要运行多次的事情,那么在文件中索引记录或使用数据库可能有所帮助,但如果这是一次性操作(由于您仍然需要阅读整个文件一次创建索引/数据库)。
使用更快的存储媒体。
如果你没有受到I / O限制,那么下一个最可能的情况就是你的内存受限 - 数据不会一次全部适合内存,导致磁盘在将数据块移入数据库时发生颠簸并且没有虚拟内存。再次,并行化过程会使事情变得更糟,而不是更好。
此案例中的解决方案与以前类似:
更改您正在执行的操作,以便您不需要同时在内存中存储所有数据。在这种情况下,即使是一次性操作,索引或数据库也可能是有益的。
购买更多内存。
除非你对数据进行更多的处理,而不是只使用几个正则表达式并将其填充到你已经显示的哈希值中,否则你肯定不 CPU绑定并且并行化将会不提供任何好处。