2010-07-22 96 views
1

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

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线程。
  • 分离进程,然后通过管道检索散列。
+0

如何编写C扩展? – CodeJoust 2010-07-22 20:44:20

+0

您使用的是Ruby 1.8还是1.9? 1.9可以比1.8快10-20%(在这种情况下,这是一个更大的增长)。 – Digikata 2010-07-22 22:40:08

+0

我正在使用1.9.1 – 2010-07-23 17:33:15

回答

2

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

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

如果他们太大,不适合到内存中,它变得更加复杂,你必须设置数据,然后解析,或螺纹的块读取具有独立的读取和解析线程。

+0

这确实刮了大约30秒,但它仍然需要2分钟。 – 2010-07-22 21:59:25

+0

我发现这样做后,对该方法进行其他改动减少了时间。有了这个和其他改进,现在已经到了可以接受的时间。 – 2010-08-09 17:23:09

0

我不太了解Ruby,但之前我不得不面对这个问题。我发现最好的办法是将文件分割成块或单独的文件,然后产生线程一次读取每个块。一旦分区文件在内存中,结果应该很快。这里是的Ruby on线程的一些信息:

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

希望有所帮助。

+0

分割它真的有帮助吗?因为,正如我提到的那样,当我为每个文件使用线程时,它只会变慢。 – 2010-07-22 20:54:50

2

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

+0

+1,尽管在简单键/值的“一次加载”阶段之后,这可能不太好。另一种选择是BDB风格(Berkley-DB)风格的后端,如果它只是一个简单的键/值存储,而不需要额外的SQL关系和连接。 – 2010-07-22 21:02:04

1

(是不同的,虽然我第一次建议寻找(Ruby) BDB等“NoSQL的”后端 - 发动机,是否符合您的需求。)

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

与线程这里的一般问题是:

  1. 的IO将可能左右红宝石“绿色”主题的瓶颈
  2. 你仍然需要在使用前的所有数据

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

+0

创建数据库所花的时间令人无法忍受。 – 2010-08-09 17:21:05