Arrays 大型参考文件(800000行)。存储在数组中或使用文件句柄
我有一个非常大的以制表符分隔的文件,其中包含信息Arrays 大型参考文件(800000行)。存储在数组中或使用文件句柄,arrays,perl,memory,file-io,size,Arrays,Perl,Memory,File Io,Size,我有一个非常大的以制表符分隔的文件,其中包含信息 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 .
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行)
我在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;
}
}
}
}
#/usr/bin/perl-w
严格使用;
foreach(@coord){
my@query=split(/\t/,$);
chomp@query;#清理
foreach(@ref){
我的@ref\u行=拆分(/\t/,$);
在参考线上咀嚼;清理
如果($query[1]>=$ref_line[3])&($query[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有20000个chr9,那就是20,000次点击,但是如果ref只有3个保持坐标的位置,那么点击的数量将是3,这可能是真的,但并不重要;你仍然会对1800*800000个组合进行一些检查;只需一次在一个散列中查找这20000个,甚至不接触其他位置,应该会有很大的不同伟大的建议!什么40分钟的搜索现在是3分钟。哇!将使用警告;
添加到文件的开头,而不是将-w
添加到shebang(#!
)行。您还应该在其中添加使用严格;
。
foreach ( @{ $ref{ $query[0] } } ) {