我的程序使用了两个大文本文件(数百万行)。这些文件被解析并加载到哈希中,以便可以快速访问数据。我面临的问题是,目前,解析和加载是程序中最慢的部分。以下是完成此操作的代码。
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
....
我用不同的方式设置文件并解析它们,到目前为止这是最快的方法,但它仍然非常慢。
有没有办法提高速度,或者我可以采取其他方法吗?
不起作用的事项列表:
答案 0 :(得分:2)
为什么不使用几十年经验设计的解决方案:一个数据库,比如SQLite3?
答案 1 :(得分:2)
在我的使用中,在解析之前将全部或部分文件读入内存通常会更快。如果数据库大小足够小,这可能就像
一样简单buffer = File.readlines(database)
buffer.each do |line|
...
end
如果它们太大而无法适应内存,则会变得更加复杂,您必须设置数据的块读取,然后解析,或者使用单独的读取和解析线程进行线程化。
答案 2 :(得分:1)
(有所不同,虽然我首先建议查看(Ruby) BDB和其他“NoSQL”后端引擎,如果它们符合您的需要。)
如果使用具有确定性索引的固定大小的记录,则可以通过代理对象对每个项目执行延迟加载。这将是mmap的合适候选者。但是,这将不加快总访问时间,但只会在程序的整个生命周期中分摊加载(至少在第一次使用之前,如果从未使用某些数据,那么你会得到永远不会加载它的好处)。如果没有固定大小的记录或确定性索引值,这个问题会更复杂,并且看起来更像传统的“索引”存储(例如,SQL后端的B树或BDB使用的任何一个: - )。
线程的一般问题是:
您可能对Widefinder Project感兴趣,通常只是“尝试加快IO处理速度”。
答案 3 :(得分:0)
我对Ruby知之甚少,但我之前不得不处理这个问题。我发现最好的方法是将文件拆分为块或单独的文件,然后生成线程以一次读取每个块。一旦分区文件在内存中组合,结果应该很快。以下是Ruby中Threads的一些信息:
http://rubylearning.com/satishtalim/ruby_threads.html
希望有所帮助。