2

これは私の Perl を改善する試み です:私がやろうとしていたことをより徹底的に説明することにより、バイトではなくビットをシークして読み取ります。

ファイルに非常に効率的に格納したい 9136 x 42 の整数配列 x があります。整数には次の制約があります。

  • x[0..9135][0] の 9136 個の整数はすべて -137438953472 から 137438953471 の間にあるため、38 ビットを使用して格納できます。

  • x[0..9135][1] の 9136 個の整数はすべて -16777216 から 16777215 の間であるため、25 ビットを使用して格納できます。

  • など... (整数ビットの制約は事前にわかっています; Perl はそれらを計算する必要はありません)

質問: Perl を使用して、この配列をファイルに効率的に格納するにはどうすればよいですか?

ノート:

  • 整数を 25 ビットで格納できる場合は、7 ビットを無駄にしたくない場合は、4 バイト (32 ビット) で格納することもできます。ただし、私の状況では、すべてのビットが重要です。

  • ファイルを順番に読み取るのではなく、ファイル 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 ビット長であることを記憶していることに注意してください。ただし、ファイルが 2 つの単純な 64 ビット整数を格納するために必要な 16 バイトよりも短いです。

この情報をどうするかはあなた次第ですが、このようにパックされたデータは 16 進エディタでデバッグするのが非常に難しいことに注意してください。このようなものを採用すると、自分の足を撃っている可能性があります。

于 2014-08-27T21:55:39.227 に答える