【问题标题】:Large reference file (800,000 lines). Store in array or use filehandle大型参考文件(800,000 行)。存储在数组中或使用文件句柄
【发布时间】:2014-01-31 15:01:52
【问题描述】:

我有一个包含信息的非常大的制表符分隔文件。

chr9    refFlat exon    136333685   136335910   .   +   .   gene_id "CACFD1"; transcript_id "NM_001242370"; exon_number "5"; exon_id "NM_001242370.5"; gene_name "CACFD1";  
chrX    refFlat exon    51804923    51805135    .   -   .   gene_id "MAGED4B"; transcript_id "NM_001242362"; exon_number "14"; exon_id "NM_001242362.1"; gene_name "MAGED4B";

我有另一个包含搜索坐标的文件(1800 行)

chr11   62105438 
chr11   85195064 
chr17   33478139 
chr21   9827089

我在 for 循环中有一个嵌套的 for 循环,其中坐标文件中的每一行都针对参考文件进行搜索。

#!/usr/bin/perl -w

use strict; 

    foreach(@coord){

                my @query = split(/\t/,$_);
                chomp @query; #clean up

                foreach(@ref){

                        my @ref_line = split(/\t/,$_);
                        chomp @ref_line; #clean up

                        if(($query[1] >= $ref_line[3]) && ($query[1] <= $ref_line[4])){

                                if ($query[0] eq $ref_line[0]){

                                        my @sub_ref_line = split(";",$ref_line[8]);
                                        $results {"$query[0],$query[1]"} = "$sub_ref_line[4]";
                                        next;
                                }
                        }
                }
        }

为了速度和内存,我使用文件句柄作为引用而不是将其存储在数组中会更好吗?

【问题讨论】:

  • use warnings; 添加到文件的开头,而不是将-w 添加到shebang (#!) 行。你也应该在里面有use strict;

标签: arrays perl memory file-io size


【解决方案1】:

您想先将参考文件读入哈希,如下所示:

my %ref = (
    'chr9' => [
        'chr9    refFlat exon    136333685   136335910   .   +   .   gene_id "CACFD1"',
        # any other lines with chr9
    ],
    'chrX' => [
        ...
    ],
    ...
);

然后在你的内部循环中,你可以只循环那些具有匹配第一个字段的参考文件行:

    foreach ( @{ $ref{ $query[0] } } ) {

您只使用了稍微多一点的内存,但如果平均 chr# 出现 20000 次,您进入内部循环的次数是 3600 万次,而不是 14.4 亿次。

要回答您的实际问题,在内部循环中读取文件而不是在内存中保存参考数据将占用更少的内存,但速度会慢得多。

【讨论】:

  • 我决定先查询坐标而不是 chr# 的原因是因为我会得到更少的点击。这是不好的想法吗?例如,如果 ref 有 20,000 chr9,即 20,000 次命中,但如果 ref 只有 3 个位置保存坐标,则命中数将为 3
  • 这可能是真的,但并不重要;您仍然需要检查 1800*800000 组合;只需一次在哈希中查找这 20000 个,甚至不碰其他人应该会有很大的不同
  • 很好的建议!现在大约 40 分钟的搜索是什么,大约 3 分钟的搜索。哇!
猜你喜欢
  • 1970-01-01
  • 2015-07-12
  • 1970-01-01
  • 2017-04-21
  • 2011-12-04
  • 1970-01-01
  • 1970-01-01
  • 2011-06-01
  • 2017-02-08
相关资源
最近更新 更多