【问题标题】:Increasing the Loading Speed of Large Files提高大文件的加载速度
【发布时间】:2010-07-22 20:39:50
【问题描述】:

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

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 线程。
  • 分叉进程,然后通过管道检索哈希。

【问题讨论】:

  • 写一个C扩展怎么样?
  • 您使用的是 Ruby 1.8 还是 1.9? 1.9 可以比 1.8 快 10-20%(在 Windows 上,这种情况的增长幅度更大)。

标签: ruby performance


【解决方案1】:

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

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

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

【讨论】:

  • 这确实缩短了大约 30 秒,但仍然需要 2 多分钟。
  • 我发现在这样做之后,对方法进行其他更改会减少时间。有了这个和其他的改进,现在已经可以接受了。
【解决方案2】:

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

【讨论】:

  • +1,尽管在简单键/值的“一次加载”阶段之后这可能不会更好。另一种选择是 BDB 风格 (Berkley-DB) 风格的后端,如果它只是一个简单的键/值存储并且不需要额外的 SQL 关系和连接。
【解决方案3】:

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

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

这里线程的一般问题是:

  1. IO 将可能成为 Ruby“绿色”线程的瓶颈
  2. 使用前您仍然需要所有数据

您可能对Widefinder Project 感兴趣,一般来说是“试图获得更快的 IO 处理”。

【讨论】:

  • 创建数据库所花费的时间令人难以忍受。
【解决方案4】:

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

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

希望对您有所帮助。

【讨论】:

  • 拆分真的有用吗?因为,正如我所提到的,当我为每个文件使用一个线程时,它只会变慢。
猜你喜欢
  • 2016-08-03
  • 2014-09-28
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 2014-12-03
  • 1970-01-01
相关资源
最近更新 更多