【问题标题】:Perl : Parallel or multithread or Bloom-Faster or fork to fill hash from a file of 500 million linesPerl:并行或多线程或 Bloom-Faster 或 fork 从 5 亿行的文件中填充哈希
【发布时间】:2013-12-04 18:06:19
【问题描述】:

像并行运行一样更快地执行此脚本的最佳解决方案是什么?

#!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;

【问题讨论】:

  • 你能重新编辑你的问题吗?看起来整个事情现在都在一条线上....
  • @andrewsi:整件事只写了几行。我已经或多或少地修复了它。
  • 欢迎来到 Stack Overflow。请尽快阅读About 页面。格式化代码时,请确保您有换行符,避免使用制表符,按照您希望的方式布置代码(建议每级缩进 4 个空格),然后选择所有代码并使用 {} 按钮在编辑框上方进行缩进,使其与上面一样。然后请在正文中添加一个问题;您不能将整个问题留在标题/主题中。
  • @JonathanLeffler - 你比我更有耐心!
  • 你发布的不是 IO-bound 吗?如果是这样,投入更多 CPU 有什么帮助。

标签: perl


【解决方案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 已经指出的那样,您可能会发现从媒体读取是实际的瓶颈。

【讨论】:

  • 你能给我看一个简短的例子吗?我怎样才能使内存休眠,何时可以重新激活其余部分的读取,休眠时间是否足以将读取的行写入内存并将索引保​​存在 hash 中。我应该使用 readline 函数而不是 seek 吗? Perldoc 中的这些问题并不完全可以理解。我是 perl 用户而不是开发人员。感谢您的帮助
  • @user3064106 它需要一些调整 => stackoverflow.com/a/16989501/223226
【解决方案2】:

最可能的情况是您受到从磁盘读取数据的速度(“I/O 限制”)的限制,而不是处理时间(“CPU 限制”)的限制。如果是这种情况,那么没有您可以使用线程或并行执行来加快速度 - 如果它有任何影响,并行化会通过强制磁盘跳回并减慢您的速度在被不同进程/线程读取的文件部分之间来回移动。

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

  1. 更改代码的工作方式,这样您就无需阅读整个文件。如果您正在处理将运行多次的内容,则在文件中索引记录或使用数据库可能会有所帮助,但如果它是一次性操作(因为您仍然需要阅读整个文件一次以创建索引/数据库)。

  2. 使用速度更快的存储介质。

如果您不受 I/O 限制,则下一个最可能的情况是您受内存限制 - 数据不会一次全部放入内存,导致磁盘在将数据块移动到并且没有虚拟内存。再一次,并行化过程会使事情变得更糟,而不是更好。

本例的解决方法与之前类似:

  1. 改变你正在做的事情,这样你就不需要一次内存中的所有数据。在这种情况下,即使是一次性操作,索引或数据库也可能是有益的。

  2. 购买更多内存。

除非您对数据进行大量处理,而不仅仅是几个正则表达式并将其填充到您所展示的哈希中,否则您绝对不会受 CPU 限制,并且并行化将不提供任何好处。

【讨论】:

  • my_data_file > /dev/null 花费时间然后程序执行(4 分钟)。我的意思是我受内存限制?
  • 受内存限制看起来是最有可能的情况,是的。假设您使用的是 *nix 类型的系统,您可以通过使用free 命令在程序运行时获取内存使用情况的快照或使用top 实时查看它来验证这一点。
猜你喜欢
  • 1970-01-01
  • 2016-08-29
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2021-02-15
  • 1970-01-01
相关资源
最近更新 更多