2

私のPHPプログラムは、0から7の範囲の値の配列を処理しています。これらの値をPHPに格納するための最も効果的な方法を見つけようとしています。最も効果的なのは、使用するビット数を減らすことです。

各値に必要なストレージスペースは3ビット(b000=0からb111=7)のみであることは明らかです。しかし、これらの3ビット値をバイナリ文字列に格納する最も効率的な方法は何ですか?

保存または復元する必要のある3ビット値の数は事前にわかりませんが、大量になる可能性があるため、64ビットでは明らかに不十分です。

pack()とunpack()を調べていました。各バイトに2つの値を格納し、pack('C'、$ twoValues)を使用できましたが、それでも2ビットが失われています。

それは機能しますか?それらの値を保存するより効果的な方法はありますか?

ありがとう

4

5 に答える 5

1

最良の方法は、それらを整数として格納し、少しずつパックすることに関与しないことです。実際のエンジニアリング上の理由がない限り、これらを3ビット値として保存する必要があります(たとえば、ハードウェアとのインターフェース)。特に奇数ビットサイズの場合、これを行うと直接アクセスするのがかなり難しくなることに注意してください。また、これらの値をデータベースに固定している場合、このようにパックされた値を検索したり、インデックスを作成したりすることはできません。それらを整数として格納するか、dbの場合は、おそらく短い整数またはバイトとして格納します。

于 2010-08-26T21:54:04.780 に答える
1

この種のテクニックが必要になるのは、これらが少なくとも5億個ある場合だけです。考えてみてください。CPUは、あるレジスタにデータを、別のレジスタにマスクを、そしてそれらをANDして、値を取得する必要があります。ここで、その種のスペース節約手法を正当化するのに十分な長さのこれらのリストを反復処理することを想像してみてください。スペースが50%削減され、桁違いに遅くなります。

于 2010-08-26T21:59:21.277 に答える
1

多くの人が示唆しているように、この種のスペース圧縮の利点は、追加の処理で簡単に失われるので、それが良いアイデアかどうかは尋ねませんでしたが、それは別のトピックです:)

また、後でデータを保存する場所についても言及していません。そのストレージの場所/エンジンが何であれ、さらに条件や特殊なタイプがある可能性があります(たとえば、データベースにはバイナリ列形式、バイト列形式、ビットストレージなどがサポートされている場合があります)。

しかし、このトピックに固執すると、最良の3ビットストレージはニブル(1ビットをウエスト)として使用することであり、2つのニブルを1バイトに結合する(全体で2ビットを失う)と思います。はい、2ビットを失っています(それが重要な場合)が、2つの値を組み合わせるのは簡単なので、処理のオーバーヘッドは比較的小さくなります。

$byte=$val1*7+$val2;
$val2=$byte%7;$val1=($byte-$val2)/7;

バイトが使用できない場合は、これらを組み合わせて16(4格納)、32(8)、64(16)ビット整数にすることができます。これらの値の配列を作成して、より大きなストレージにすることもできます。

上記の方が人間が読める形式だと思いますが、ビットロジックを使用して値を組み合わせたり分離したりすることもできます。

$combinedbyte=$val1<<3|$val2;
$val2=$combinedbyte&7;$val1=($combinedbyte&56)>>3);

(これは事実上、PACK / UNPACKコマンドが行うことです)

または、ASCIIで最初のいくつかが保護されているため、文字にエンコードすることもできます(A-Z + 6 punc + azは、2つの値を格納するために49が必要な場合に58を提供します)。

$char=chr(($val1*7+$val2)+65); //ord('A')=65
$val2=(ord($char)-65)%7;$val1=(ord($char)-65-$val2)/7;

これらのエンコードされた一連の文字は、配列として、またはnullで終了する文字列として格納できます。

注:上記の-say- 64ビット整数の場合、3ビットを4に格納しているため、64/4=16の格納場所を取得します。これは、さらに16ビット(場所ごとに1ビット)を無駄にしていることを意味するため、さらに5つの値を追加して、合計21ビット(21 * 3 = 63ビット、1つだけが無駄になります)になりたくなるかもしれません。それは確かに可能です(整数演算では-ほとんどのPHPインスタンスは64ビットまたはビットロジックソリューションでは機能しませんが)、長期的には事態を複雑にします-おそらくそれが価値があるよりも多くの問題があります。

于 2010-08-30T16:15:46.900 に答える
0

http://php.net/manual/en/language.types.phpを見ると、整数として保存する必要があります。ただし、問題は、1つの整数値が多くの3ビット値を表すようにするかどうかです。前者はより複雑ですが、必要なメモリが少なくて済みますが、前者はその逆です。使用するメモリの量を極端に減らす必要がない場合は、後者をお勧めします(1つの3ビット値に1つの整数を使用します)。

1つの整数に多くの3ビット値を格納する際の主な問題は、3ビット値がいくつあるかを把握することです。整数の配列を使用してから、3ビット値の総数を示す追加の整数を使用できます。ただし、マニュアルにも記載されているように、整数値に使用されるビット数はプラットフォームによって異なります。したがって、整数が32ビットか64ビットかを知る必要があります。そうしないと、格納する値が多すぎてデータが失われる可能性があります。そうしないと、必要以上のメモリを使用するリスクがあります(これは目的としては悪いことです)。そもそもメモリをほとんど使用しないため)。

于 2010-08-26T21:59:46.900 に答える
0

各整数をバイナリに変換し、それらすべてを連結してから、結果の文字列をバイトに分割します。各バイトは0〜255になるため、個別の文字として格納できます。

于 2010-08-26T21:50:30.677 に答える