メモリと CPU 使用率の点でより効率的なのは、booleans の配列と BitSet のどちらですか? 特定の BitSet メソッドは使用されず、get/set/clear (配列に対してそれぞれ ==、=、Arrays.fill) のみが使用されます。
8 に答える
Boolean[]ブール値ごとに約 4 ~ 20 バイトを使用します。boolean[]ブール値ごとに約 1 バイトを使用します。BitSetブール値ごとに約 1 ビットを使用します。
メモリサイズは問題にならないかもしれません。その場合、boolean[] の方がコーディングが簡単な場合があります。
あなたの質問の少し左のフィールドですが、ストレージが懸念される場合は、Huffman compressionを調べてください。たとえば、00000001周波数によって に相当するものに絞り込むことができます{(7)0, (1)1}。より「ランダム化された」文字列00111010は、より複雑な表現 (たとえば ) を必要とし、より{(2)0, (3)1, (1)0, (1)1, (1)0}多くのスペースを占有します。ビット データの構造によっては、BitSet.
メモリに関しては、 a のドキュメントにBitSetはかなり明確な意味があります。特に:
すべてのビット セットには現在のサイズがあります。これは、ビット セットによって現在使用されているスペースのビット数です。サイズはビット セットの実装に関連するため、実装によって変わる可能性があることに注意してください。ビット セットの長さは、ビット セットの論理長に関連し、実装とは別に定義されます。
Java ライブラリ クラスのソースは公開されており、自分で簡単に確認できます。特に:
The internal field corresponding to the serialField "bits".
89
90 private long[] words;
速度に関しては; それは人が何をしているかによります。一般に、事前に速度について考えないでください。意味的に最も意味があり、最も明確なコードにつながるツールを使用してください。パフォーマンス要件が満たされていないことを観察し、ボトルネックを特定した後にのみ最適化してください。
SO に来て、A が B よりも速いかどうかを尋ねるのは、次のような多くの理由でばかげています。
- アプリケーションによって異なりますが、通常、応答する人は誰もアクセスできません。それが使用されているコンテキストで分析し、プロファイリングします。それが実際に最適化する価値のあるボトルネックであることを確認してください。
- 速度について尋ねるこのような質問は、通常、OP が効率を気にかけていると考えているが、プロファイリングする意思がなく、パフォーマンス要件を定義していないことを示しています。水面下では、これは通常、OP が間違った道を進んでいるという危険信号です。
これは古い質問ですが、最近出てきました。これは追加する価値があると思います。
それはいつものように依存します。はい、BitSet の方がメモリ効率が高くなりますが、マルチスレッド アクセスが必要になるとすぐに、boolean[] の方が適している可能性があります。たとえば、素数を計算する場合は、ブール値を true に設定するだけなので、実際には同期は必要ありません。Hans Boehmはこれについていくつかの論文を書いており、グラフ内のノードをマークするために同じ手法を使用できます。
Java から CPU への移行は、完全に VM 固有です。たとえば、以前はブール値は実際には 32 ビット値として実装されていました (現在でもおそらくそうです)。
それが問題になることがわかっていない限り、コードを明確に記述し、プロファイリングしてから、遅い部分や大量のメモリを消費する部分を修正することをお勧めします。
あなたが行くようにこれを行うことができます。たとえば、プロファイラーでコードを実行したときに (メモリの使用量が少ないにもかかわらず) 速度が大幅に低下したため、文字列で .intern() を呼び出さないことにしたことがあります。
BitSet の方がメモリ効率と CPU 効率が高いと思います。ビットを int、long、またはネイティブ データ型に内部的にパックできるのに対し、boolean[] はデータのビットごとに 1 バイトが必要です。さらに、他の方法 (and、or など) を使用する場合、配列のすべての要素を反復処理する必要がないため、BitSet の方が効率的であることがわかります。代わりにビット演算が使用されます。