15

ByteBufferaをすべてゼロバイト(all )に「クリーンアップ」しようとしています0x00。バッファ内のすべての位置をループしてに設定しようとしました0x00が、効率が悪いです。をすばやくクリアするためのより良い方法はありますByteBufferBitSet.clear()

このシナリオでは、これは適切な解決策ではないことに注意してくださいByteBuffer.clear()。ポインタを先頭にリセットするだけでなく、バ​​ッファ内のすべてのデータを消去する必要があります。

ヒントはありますか?

編集:ByteBufferはハッシュテーブルの一部として使用され、ハッシュテーブルエントリの参照を維持します。ハッシュテーブルをフラッシュする必要があるたびに、後でハッシュテーブルを挿入するためにハッシュテーブルエントリをリセットする必要があります。ハッシュテーブルはランダムにアクセスされるため、バイトバッファの状態を単純にclear()することはできません。

4

4 に答える 4

10

ByteBuffer.put(byte[])またはメソッドの1つを使用してByteBuffer.put(ByteBuffer)、一度に複数のゼロを書き込んでみましたか?次に、ゼロが事前に入力された配列またはバッファーを使用して、100バイトまたは1000バイトなどのチャンクでバッファーを反復処理できます。

欠点:これはオプションの操作であるため、ByteBufferのすべての実装がそれを提供する必要があるわけではありません...

于 2012-06-25T21:52:56.363 に答える
4

オプションのメソッド(returns )ByteBufferを提供する実装の場合、このメソッドを使用して、基になる配列への参照を取得してから、を使用できます。array()hasArray()truejava.util.Arrays#fill()

于 2012-06-25T23:19:03.237 に答える
2

ByteBufferハッシュテーブルがフラッシュされた後に新しいクリーンなゼロフィルが必要な場合、最も簡単な方法は、既存のものを削除しByteBufferて新しいものを割り当てることです。公式ドキュメントにはそのようには書かれていませんが、すべての既知の実装は新しいバッファのメモリをゼロにします。詳細については、 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6535542を参照してください。

于 2012-08-30T07:02:23.493 に答える
2

DNAが言及しているように、事前に充填されたバッファーを用意して使用するByteBuffer.put(ByteBuffer)のが、おそらく最速のポータブルな方法です。Arrays.fillそれが実用的でない場合は、次のいずれかを利用するために、またはUnsafe.putLong該当する場合は、次のようなことを行うことができます。

public static void fill(ByteBuffer buf, byte b) {
    if (buf.hasArray()) {
        final int offset = buf.arrayOffset();
        Arrays.fill(buf.array(), offset + buf.position(), offset + buf.limit(), b);
        buf.position(buf.limit());
    } else {
        int remaining = buf.remaining();
        if (UNALIGNED_ACCESS) {
            final int i = (b << 24) | (b << 16) | (b << 8) | b;
            final long l = ((long) i << 32) | i;
            while (remaining >= 8) {
                buf.putLong(l);
                remaining -= 8;
            }
        }
        while (remaining-- > 0) {
            buf.put(b);
        }
    }
}

設定UNALIGNED_ACCESSには、JREの実装とプラットフォームに関するある程度の知識が必要です。JNA(システムプロパティPlatform.ARCHにアクセスするための便利で標準的な方法として提供されます)も使用する場合に、OracleJRE用に設定する方法は次のとおりです。os.arch

/**
 * Indicates whether the ByteBuffer implementation likely supports unaligned
 * access of multi-byte values on the current platform.
 */
private static final boolean UNALIGNED_ACCESS = Platform.ARCH.startsWith("x86");
于 2017-03-12T22:16:08.103 に答える