2012-06-25 4 views
10

ByteBuffer을 "정리"하여 모든 0 바이트 (모두 0x00)가되도록하려고합니다. 나는 버퍼의 모든 위치를 반복하려하고 그것들을 0x00으로 설정했지만 효율성은 좋지 않습니다. ByteBuffer - BitSet.clear()과 비슷한 것을 빨리 삭제할 수있는 더 좋은 방법이 있습니까?Java에서 ByteBuffer를 빠르게 지우기 (지울 수 없음)

이 시나리오에서는 ByteBuffer.clear()이 적절한 해결책이 아니므로 버퍼 안의 모든 데이터를 지우고 포인터를 처음으로 다시 설정해야합니다.

힌트가 있습니까?

편집 : ByteBuffer는 해시 테이블의 일부로 사용되며 해시 테이블 항목의 참조를 유지 관리합니다. 해시 테이블을 플러시해야 할 때마다 나중에 해시 테이블 삽입을 위해 해시 테이블 항목을 다시 설정해야합니다. 해시 테이블은 무작위 방식으로 액세스되기 때문에 단순히 바이트 버퍼의 상태를 지울 수 없습니다().

+0

더 자세히 설명 할 수 있습니까? 바이트 버퍼를 어떻게 얻습니까? – jontro

+0

버퍼를 제로화해야한다고 생각하는 이유는 무엇입니까? – EJP

+0

직접 버퍼입니까? 그렇지 않다면, 단지 ByteBuffer.wrap (new byte [123456]);은 무엇 이냐? –

답변

6

ByteBuffer.put(byte[]) 또는 ByteBuffer.put(ByteBuffer) 방법 중 하나를 사용하여 한 번에 여러 개의 0을 써 봤습니까? 그런 다음 0 또는 1000 바이트가 미리 채워진 배열이나 버퍼를 사용하여 버퍼를 반복 할 수 있습니다.

단점 : 옵션 array() 방법 (hasArray() 반환 true 어디), 당신이 사용할 수 제공 ByteBuffer 구현의

+0

시도해 보겠습니다. 다행히 대량 조립은 루프보다 좋을 것입니다 ... thx! – asksw0rder

+2

이 늦은 답변을 드려 죄송합니다. 그러나이 방법은 실제로 플러시 오버 헤드를 줄이는 데 효과적입니다. 플러싱 시간이 ~ 60ms에서 ~ 2ms로 감소한 것을 보았습니다. 그것이 충분히 좋은지 볼 것입니다. – asksw0rder

4

...이 선택적인 작업입니다, 그래서하지의 ByteBuffer의 모든 구현을 제공해야합니다 메서드가 기본 배열에 대한 참조를 가져온 다음 java.util.Arrays#fill()을 사용하십시오.

1

해시 테이블이 플러시 된 후 깨끗한 0으로 채워진 ByteBuffer가 필요한 경우 가장 쉬운 방법은 기존 ByteBufefr을 잊어 버리고 새 ByteBufefr을 할당하는 것입니다. 공식 문서는 그렇게 말하지 않지만 모든 알려진 구현은 새로운 버퍼의 메모리를 제로화합니다. 자세한 내용은 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6535542을 참조하십시오.

1

DNA에 언급되어 있듯이 미리 채워진 버퍼를 가지고 ByteBuffer.put(ByteBuffer)을 사용하면 아마도 가장 빠른 휴대용 방법 일 것입니다.

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 구현과 플랫폼에 대한 약간의 지식이 필요합니다 그 실용적이지의 경우, 해당되는 경우 Arrays.fill 또는 Unsafe.putLong 중 하나를 활용하기 위해이 같은 일을 할 수 있습니다. 다음은 JAC (을 편리한 표준 방법으로 os.arch 시스템 속성에 액세스하도록 제공)을 사용하는 경우 Oracle JRE 용으로 설정하는 방법입니다.

/** 
* 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"); 
관련 문제