如何优化表查找

时间:2017-11-20 09:15:54

标签: perl optimization

My Perl脚本解析如下文件:

    chr   start   end   strand
    chr1  11870 11891   +
    chr1  28537 28558   +
    chr1  46502 46523   +
    chr1  39909 39930   -
    chr1  43896 43917   -
    chr2  62774 62795   -

strand+时,start保留end并搜索strand - 11870 39930 11870 43917 28537 39930 28537 43917 条记录,以配对启动和结束价值。

结果如下:

start

为此,我制作两张桌子。我创建了一个包含+ strand end - strand的表和另一个包含start start positionend的表格。然后,对于end position我的表格中的每个start,我搜索################## #!/usr/bin/perl use strict; use warnings; use Bio::SeqIO; use Data::Dumper; open C, "<$ARGV[0]" or die "Impossible d'ouvrir le fichier"; my ( @pair_start, @pair_end ); while ( my $ligne = <C> ) { chomp $ligne; my @tab = ( split /\t/, $ligne ); while ( $tab[0] =~ m/chr[0-9]/gi ) { my $chr = $tab[0]; my $start = $tab[1]; my $end = $tab[2]; my $strand = $tab[3]; if ( $strand eq "+" ) { push @pair_start, $start; } elsif ( $strand eq "-" ) { push @pair_end, $end; } } } my $seqio_obj = Bio::SeqIO->new( -file => "$ARGV[1]", -format => "fasta" ); my $cpt_seq = 0; my $seq_obj = $seqio_obj->next_seq; foreach my $pair_start ( @pair_start ) { foreach my $pair_end ( @pair_end ) { if ( $pair_start < $pair_end ) { my $sous_seq = $seq_obj->subseq( $pair_start, $pair_end ); my $length = length( $sous_seq ); if ( $length > 43 && $length < 4000 ) { $cpt_seq++; } } } } print "il y a $cpt_seq séquences\n"; (在表@Query(value = "SELECT new com.test.book.BookStats(b.author, b.title, count(b)) from Book b where b.title = :#{#filter.title} and b.author= :#{#filter.author}") List<BookStats> calculateBookStats (@Param("filter") Filter filter) 中),其大于我的{{1}}。

我的问题是它需要花费太多时间,我会尝试考虑一些不需要制作两个表或“动态表”的东西。

如果没有这两个表,你有没有想法进行搜索?

脚本:

{{1}}

1 个答案:

答案 0 :(得分:1)

你的问题不是很清楚,但我认为这就是你的意思。我假设您只想比较相同染色体内的子序列

此代码的工作原理是存储一个数组散列,其中包含startend值的列表以及每个染色体的strand指示符。然后每个列表按位置排序,以便我们在列表中的每个end位置之后查找所有start个位置

两个for循环只打印每个染色体所需的信息

该程序需要命令行上输入文件的路径,并将输出写入STDOUT

use strict;
use warnings 'all';

my ( %data, @chr);

while ( <> ) {
    my ( $chr, $start, $end, $strand ) = split;
    next if $start =~ /\D/;

    push @chr, $chr unless $data{$chr};

    push @{ $data{$chr} }, $strand eq '+' ? [ $start, $strand ] : [ $end, $strand ];
}

for my $chr ( @chr ) {

    my $data = $data{$chr};

    @$data = sort { $a->[0] <=> $b->[0] } @$data;

    for my $i ( 0 .. $#$data ) {
        next unless $data->[$i][1] eq '+';

        for my $j ( $i + 1 .. $#$data ) {
            next unless $data->[$j][1] eq '-';

            print join( ' ', $chr, $data->[$i][0], $data->[$j][0]), "\n";
        }
    }
}

输出

chr1 11870 39930
chr1 11870 43917
chr1 28537 39930
chr1 28537 43917