更快地搜索Perl中的文件

时间:2011-11-28 06:44:33

标签: performance perl file search for-loop

我遇到一个问题,我当前的算法使用简单的线性搜索算法通过匹配的字符串从多个数据文件中检索数据。

就像这样(伪代码):

while count < total number of files
     open current file
     extract line from this file
     build an arrayofStrings from this line

     foreach string in arrayofStrings
          foreach file in arrayofDataReferenceFiles
               search in these files

     close file
     increment count

对于大型的现实生活工作,一个过程可能需要大约6个小时才能完成。

基本上我有一大组字符串,它们使用程序搜索同一组文件(例如,10个实例,在下一个实例中可以运行3个)。由于参考数据文件可以更改,我认为构建这些文件的永久索引并不聪明。

我几乎是初学者,并不知道任何更快的未分类数据技术。

我在想,因为搜索在一段时间后会重复,是否可以在构建文件数组(文件已知)后预先建立数据引用文件中特定行的位置索引而不使用任何外部perl库?此脚本将被移植到可能只安装了标准Perl的服务器上。

我认为在处理作业之前花费3-5分钟为搜索构建某种索引可能是值得的。

是否有适用于我的情况的索引/搜索的特定概念?

谢谢大家!

3 个答案:

答案 0 :(得分:3)

很难准确理解你想要实现的目标。

我认为数据集不适合RAM。

如果您尝试将许多文件中的每一行与一组模式进行匹配,最好一次读取每一行,然后将其与内存中的所有模式匹配,然后再继续。这将减少每个模式的IO过循环。

另一方面,如果匹配是花时间你可能最好使用一个可以同时匹配大量模式的库。

答案 1 :(得分:1)

您可以替换它:

foreach file in arrayofDataReferenceFiles
    search in these files

使用预处理步骤构建DBM文件(即磁盘上的哈希)作为反向索引,将参考文件中的每个单词映射到包含该单词的文件列表(或任何您需要的文件)。 Perl核心includes DBM support

  

dbmopen HASH,DBNAME,MASK

     

这会将dbm(3),ndbm(3),sdbm(3),gdbm(3)或Berkeley DB文件绑定到散列。

您通常会通过tie访问这些内容,但这并不重要,每个Perl都应该支持至少一个磁盘上的磁盘库而不需要安装非核心软件包。

答案 2 :(得分:1)

正如MarkR所说,你想要从每个文件读取每行不超过一次。您发布的伪代码看起来像是在多次读取每个文件的每一行(每个搜索的单词一次),这会大大减慢速度,特别是在大型搜索时。颠倒两个最内层循环的顺序应该(通过发布的伪代码判断)解决这个问题。

但是,你说,“由于参考数据文件可以改变,我认为建立这些文件的永久索引并不聪明。”这很可能是不正确的。如果性能是一个问题(如果你有6小时的运行时间,我会说这可能会引起关注),平均而言,每个文件在对特定文件的更改之间被多次读取,然后构建索引在磁盘上(甚至......使用数据库!)将是一件非常聪明的事情。这些天磁盘空间非常便宜;人们花在等待结果上的时间不是。

即使文件经常在没有被读取的情况下经历多次更改,按需索引(当您想要检查文件时,首先查看索引是否存在,如果不存在,则在进行搜索之前构建一个)将是优秀的方法 - 当文件被多次搜索时,您将从索引中受益;当它没有时,首先构建索引,然后从索引中搜索将比线性搜索慢得多,以至于在很大程度上无关紧要。