首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将1mio Perl位向量转换为.5 mio整数数组

将1mio Perl位向量转换为.5 mio整数数组
EN

Stack Overflow用户
提问于 2014-03-03 19:15:34
回答 2查看 68关注 0票数 1

我有来自长度为1MIO的数据库的位向量,每个位代表一个整数,用于压缩存储:

代码语言:javascript
复制
the bit string : 10110001  from the database
array             2 3 0 1  needed for further processing

当前的解决方案是:

代码语言:javascript
复制
my $bitstring =
$sth->fetchrow_array();    # has 2 bits / snp, need 2 convert to I
my $snp_no = 1000000;
for ( my $i = 0; $i <= $snp_no - 1; $i++ ) {
    my $A2 = substr ($bitstring ,$j,2);
    $j = $j + 2;
    my $vec = Bit::Vector->new_Bin(32, $A2);
    @bitArray->[$i] = $vec->to_Dec();
}

这确实有效,但太慢了:处理一个这样的向量需要一秒钟,而对于数千个向量,处理过程将需要几个小时。

有没有人知道如何让这一切变得更快?

EN

回答 2

Stack Overflow用户

发布于 2014-03-03 22:07:28

如果您从“打包”的数据开始,请使用以下内容:

代码语言:javascript
复制
my @decode =
   map [
      ($_ >> 6) & 3,
      ($_ >> 4) & 3,
      ($_ >> 2) & 3,
      ($_ >> 0) & 3,
   ],
      0x00..0xFF;

my @nums = map @{ $decode[$_] }, unpack 'C*', $bytes;

对我来说,1,000,000字节大约需要1.1秒,也就是每个字节1.1微秒。

一个专门的纯C解决方案需要大约一半的时间。

代码语言:javascript
复制
use Inline C => <<'__EOI__';

void decode(AV* av, SV* sv) {
   STRLEN len;
   U8* p = (U8*)SvPVbyte(sv, len);

   av_fill(av, len*4);
   av_clear(av);
   while (len--) {
      av_push(av, newSViv(*p >> 6    ));
      av_push(av, newSViv(*p >> 4 & 3));
      av_push(av, newSViv(*p >> 2 & 3));
      av_push(av, newSViv(*(p++)  & 3));
   }
}

__EOI__

decode(\my @nums, $bytes);

如果从位的二进制表示开始,请首先使用以下内容:

代码语言:javascript
复制
my $bytes = packed('B*', $bits);

(这假设位数可以被8整除。如果不能,则使用0进行左填充,并且不要忘记删除在@decode中创建的额外条目。)

票数 1
EN

Stack Overflow用户

发布于 2014-03-03 21:36:05

这样会更快吗?

代码语言:javascript
复制
#!/usr/bin/env perl

use warnings;
use strict;

my %bin2dec = (
  '0'  => 0,
  '1'  => 1,
  '00' => 0,
  '01' => 1,
  '10' => 2,
  '11' => 3
);

#warn "$_ => $bin2dec{$_}\n" for sort keys %bin2dec;

my @results;

while (<>)
{

  foreach my $bitstring (/([01]+)/g)
  {
    my @result;

    #warn "bitstring is $bitstring\n";

    for ( my $i = 0 ; $i < length($bitstring) ; $i += 2 )
    {
      #warn "value is ", substr( $bitstring, $i, 2 ), "\n";
      push( @result, $bin2dec{ substr( $bitstring, $i, 2 ) } );
    }
    push( @results, \@result );
  }
}

foreach my $result (@results)
{
  print join( ' ', @$result ), "\n";
}

已保存到文件b2dec。输出示例:

代码语言:javascript
复制
$ echo 10010101010010010101001111001011010101w00101010 | b2dec
2 1 1 1 1 0 2 1 1 1 0 3 3 0 2 3 1 1 1
0 2 2 2
$ b2dec b2dec
0
0
1
1
0
0
1
1
2
3
1
0
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22145298

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档