提高大文件的加载速度

我的程序使用了两个大文本文件(数百万行)。 这些文件被解析并加载到哈希中,以便可以快速访问数据。 我面临的问题是,目前,解析和加载是程序中最慢的部分。 下面是完成此操作的代码。

database = extractDatabase(@type).chomp("fasta") + "yml" revDatabase = extractDatabase(@type + "-r").chomp("fasta.reverse") + "yml" @proteins = Hash.new @decoyProteins = Hash.new File.open(database, "r").each_line do |line| parts = line.split(": ") @proteins[parts[0]] = parts[1] end File.open(revDatabase, "r").each_line do |line| parts = line.split(": ") @decoyProteins[parts[0]] = parts[1] end 

文件看起来像下面的例子。 它最初是作为YAML文件开始的,但是格式被修改以提高解析速度。

 MTMDK: P31946 Q14624 Q14624-2 B5BU24 B7ZKJ8 B7Z545 Q4VY19 B2RMS9 B7Z544 Q4VY20 MTMDKSELVQK: P31946 B5BU24 Q4VY19 Q4VY20 .... 

我已经用不同的方式设置文件并解析它们,到目前为止这是最快的方法,但它仍然非常慢。

有没有办法提高速度,或者我可以采取其他方法吗?

无效的事项列表

  • YAML。
  • 标准的Ruby线程。
  • 分离进程然后通过管道检索哈希。

在我的使用中,在解析之前将全部或部分文件读入内存通常会更快。 如果数据库大小足够小,这可能很简单

 buffer = File.readlines(database) buffer.each do |line| ... end 

如果它们太大而无法适应内存,则会变得更加复杂,您必须设置数据的块读取,然后解析,或者使用单独的读取和解析线程进行线程化。

为什么不使用几十年经验设计的解决方案:一个数据库,比如SQLlite3?

(有所不同,虽然我首先建议查看(Ruby)BDB和其他“NoSQL”后端引擎,如果它们符合您的需要。)

如果使用具有确定性索引的固定大小的记录则可以通过代理对象对每个项目执行延迟加载。 这将是mmap的合适候选者。 但是,这不会加快总访问时间,但只会在程序的整个生命周期中分摊负载(至少在第一次使用之前,如果从未使用某些数据,那么您将获得永不加载它的好处)。 如果没有固定大小的记录或确定性索引值,这个问题就会变得更加复杂,并且开始看起来更像传统的“索引”存储(例如,SQL后端的B树或BDB使用的:-)。

这里线程的一般问题是:

  1. IO 可能是围绕Ruby“绿色”线程的瓶颈
  2. 使用前仍需要所有数据

您可能对Widefinder项目感兴趣,通常只是“试图加快IO处理速度”。

我不太了解Ruby,但我以前不得不处理这个问题。 我发现最好的方法是将文件拆分为块或单独的文件,然后生成线程以一次读取每个块。 一旦分区文件在内存中组合,结果应该很快。 以下是Ruby中Threads的一些信息:

http://rubylearning.com/satishtalim/ruby_threads.html

希望有所帮助。