Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl:并行或多线程或Bloom更快,或从5亿行的文件中用fork填充哈希_Perl - Fatal编程技术网

Perl:并行或多线程或Bloom更快,或从5亿行的文件中用fork填充哈希

Perl:并行或多线程或Bloom更快,或从5亿行的文件中用fork填充哈希,perl,Perl,什么是最好的解决方案,可以像并行运行一样更快地执行此脚本 #!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$//;

什么是最好的解决方案,可以像并行运行一样更快地执行此脚本

#!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;
#!usr/bin/perl
使用警告;
严格使用;
使用线程;

打开(R1,“您可以创建一个由
$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已经指出的那样,从媒体读取是实际的瓶颈。

最有可能的情况是,您受到从磁盘读取数据的速度的限制(“I/O绑定),而不是处理时间(“CPU绑定”)。如果是这样的话,那么线程或并行执行就无法加快速度——如果它有任何效果,并行化将通过强制磁盘在不同进程/线程读取的文件部分之间来回跳转来降低速度

测试是否存在这种情况的一种简单方法是打开一个shell并运行命令
cat my_data_file>/dev/null
,这应该告诉您从磁盘读取文件所需的时间,而不实际对其执行任何操作。如果这与在
my_data_file
上运行程序所需的时间大致相同,那么不要费心尝试优化或加速。你不能。在这种情况下,只有两种方法可以提高性能:

  • 更改代码的工作方式,这样您就不需要读取整个文件。如果您处理的内容将运行多次,对文件中的记录进行索引或使用数据库可能会有所帮助,但如果是一次性操作,则没有任何好处(因为创建索引/数据库时,您仍然需要读取整个文件一次)

  • 使用更快的存储介质

  • 如果您没有I/O绑定,下一个最有可能的情况是内存绑定-数据不会一次全部装入内存,导致磁盘在将数据块移入虚拟内存和移出虚拟内存时发生抖动。同样,并行化进程会使情况变得更糟,而不是更好

    这种情况下的解决方案与之前类似:

  • 更改您正在执行的操作,这样您就不需要一次将所有数据存储在内存中。在这种情况下,索引或数据库可能对一次性操作也有好处

  • 买更多的公羊


  • 除非你对数据的处理比你展示的几个正则表达式要繁重得多,并将其填充到一个散列中,否则,你肯定不会受到CPU的限制,并行化也不会带来任何好处。

    你能重新编辑你的问题吗?看起来整个问题目前都在一行上……@andrewsi:整个问题都是在几行上。我已经或多或少地修复了它。欢迎使用堆栈溢出。请尽快阅读该页。在格式化代码时,确保有换行符,避免制表符,按照您希望的样子排列代码(建议每级缩进4个空格),然后选择所有代码并使用
    {}
    按钮在编辑框上方缩进,使其看起来与上面一样。然后请在正文中添加一个问题;您不能将整个问题保留在标题/主题中。@JonathanLeffler-您比我有更多的耐心!您发布的IO不是有限制的吗?如果是这样,如何投入更多的CPU来帮助它。my_data_file>/dev/null tak等待程序执行的时间(4分钟)。我的意思是我内存不足?内存不足看起来是最有可能的情况,是的。假设您使用的是*nix类型的系统,您可以通过使用
    free
    命令在程序运行时获取内存使用情况的快照,或
    top
    实时查看它来验证这一点。您能给我举一个简短的示例吗?我该怎么做休眠内存,当我可以重新激活对其余部分的读取时,休眠时间是否足以在内存中执行读取行并将索引保存在哈希中。我是否应该使用readline函数而不是seek?Perldoc中的这些问题不完全可以理解。我是perl用户,不是开发人员。感谢您的帮助help@user3064106会的ld需要一些调整=>