2

这是改进我的 Perl 的尝试 :通过更彻底地解释我正在尝试做的事情来寻找和读取位,而不是字节。

我有 x,一个 9136 x 42 的整数数组,我想将它超高效地存储在文件中。整数具有以下约束:

  • x[0..9135][0] 中的所有 9136 个整数都在 -137438953472 和 137438953471 之间,因此可以使用 38 位存储。

  • x[0..9135][1] 中的所有 9136 个整数都在 -16777216 和 16777215 之间,因此可以使用 25 位存储。

  • 依此类推...(整数位约束是预先知道的;Perl 不必计算它们)

问题:使用 Perl,我如何有效地将这个数组存储在一个文件中?

笔记:

  • 如果一个整数可以存储为 25 位,那么它也可以存储为 4 个字节(32 位),如果您愿意浪费 7 位。然而,在我的情况下,每一点都很重要。

  • 我想使用文件 seek() 快速查找数据,而不是通过文件顺序读取。

  • 该数组通常以 x[i] 的形式访问。换句话说,我想要与给定 x[i] 对应的 42 个整数,因此这 42 个整数应该彼此靠近存储(理想情况下,它们应该在文件中彼此相邻存储)

  • 我最初的方法是只放置一个比特流,然后找到一种方法将其读回并将其改回整数。我最初的问题集中在这个问题上,但对于我没有看到的更大问题,也许有更好的解决方案。

关于我在做什么的太多细节:

4

1 回答 1

1

我不确定我应该鼓励你,但它看起来Data::BitStream会按照你的要求去做。

下面的程序将一个 38 位值和一个 25 位值写入文件,然后打开并完整地检索这些值。

#!/usr/bin/perl

use strict;
use warnings;

use Data::BitStream;

{
   my $bs_out = Data::BitStream->new(
      mode => 'w',
      file => 'bits.dat',
   );

   printf "Maximum %d bits per word\n", $bs_out->maxbits;

   $bs_out->write(38, 137438953471);
   $bs_out->write(25, 16777215);

   printf "Total %d bits written\n\n", $bs_out->len;
}

{
   my $bs_in = Data::BitStream->new(
      mode => 'ro',
      file => 'bits.dat',
   );

   printf "Total %d bits read\n\n", $bs_in->len;
   print "Data:\n";

   print $bs_in->read(38), "\n";
   print $bs_in->read(25), "\n";
}

输出

Maximum 64 bits per word
Total 63 bits written

File size 11 bytes
Total 63 bits read

Data:
137438953471
16777215

38 和 25 是写入的 63 位数据,模块确认。但是由于生成的文件的总大小为 11 个字节,而不仅仅是最小必要的 8 个字节,因此显然涉及一些额外的内务处理数据。请注意,重新打开时,数据会记住它是 63 位长。但是,它比文件必须包含两个简单的 64 位整数的 16 个字节短。

您如何处理这些信息取决于您,但请记住,以这种方式打包的数据将很难使用十六进制编辑器进行调试。如果您采用这样的方法,您可能会在自己的脚下开枪。

于 2014-08-27T21:55:39.227 回答