2012-08-22 3 views
1

Java에서 염두에 두어야 할 true/false 플래그가 100 만 개 이상 있습니다. BitSet 도움이 될까요? Set을 구현하지만 배열 요소 boolean[]처럼 빨리 요소를 반복 할 수 있습니까?긴 Java 비트 목록이 필요합니다.

질문이 있으면 죄송합니다. 먼저 배열을 int로 표시된 2 진수 청크로 분할하고 그 바이너리의 결과로 int[]을 작성하려고 했으므로 32로 크기를 줄일 수 있었지만 상당히 낮은 수준입니다.

다른 곳에서 BitSet의 일부 비평가를 발견했으며 boolean[]은 큰 배열에 많은 추가 메모리 => 불량을 저장합니다.

수백만 개의 플래그를 저장하는 더 좋은 아이디어가 있습니까?

+1

일반적인 경우 실제로 몇 개가 true로 설정 될지 알고 있습니까? 간단한'HashSet' 또는'TreeSet'는 플래그가 거의 항상 false 일 때'BitSet' 또는'boolean []'보다 훨씬 적은 메모리를 사용합니다. –

답변

2

나는 마음에 저장할 수는 false 만 개 정도 플래그 /의 배열을 가지고있다. BitSet이 도움이 될까요?

비트 집합에 수십억 비트가있을 수 있습니다.

집합을 구현하지만 배열 부울 []과 같이 빨리 요소를 반복 할 수 있습니까?

부울 []은 비트 당 1 바이트 (대부분의 JVM)를 사용하지만 BitSet은 비트 당 1 비트를 사용합니다. 작은 배열의 경우 부울 []이 더 빠르지 만 CPU 캐시의 크기를 테스트 할 때 BitSet이 더 효율적일 수 있습니다.

BTW : BitSet을 사용하면 크기가 작을 때 약간 느립니다. 메모리의 각 비트를 추출해야하기 때문입니다. byte[]에는 동일한 문제가 있으므로 비트를 직접 설정하려면 BitSet처럼 int[]을 사용하는 것이 좋습니다.


비트 세트

BitSet bitSet = new BitSet(); 
// set bit 100 
bitSet.set(100); 
// get bit 99 
System.out.println("bit 99 is " + bitSet.get(99)); 
System.out.println("bit 100 is " + bitSet.get(100) + " after set"); 
bitSet.clear(100); 
System.out.println("bit 100 is " + bitSet.get(100) + " after clear"); 

인쇄

bit 99 is false 
bit 100 is true after set 
bit 100 is false after clear 
+0

미리 지정된 크기의'int []'로했는데'boolean []'보다 빠릅니다. 'BitSet'을 사용하면 요소를 추가하는 방법을 이해하지 못했지만 그 속성에 대해 읽을 좋은 웹 페이지를 찾을 수 없습니다. 그래서 제 선택은'int []'입니다.'BitSet'보다 더 빠르기를 바랍니다. –

+0

@SophieSperner BitSet을 제외하고는 같은 속도가 될 가능성이 더 큽니다. n 번째 비트를 설정하려면'set (n)'을 호출하고 n 번째 비트를 얻으려면'get (n)'을 사용하십시오. 아마 그것이 아마도 그것보다 더 복잡하다고 상상해보십시오. ;) –

+0

@SophieSperner 예제를 추가했습니다. –

0

  • http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html에서 부울 : 참과 거짓 : Boolean 데이터 유형은 두 개의 가능한 값을 갖는다. 조건을 true/false로 추적하는 간단한 플래그에이 데이터 형식을 사용하십시오. 이 데이터 유형은 1 비트의 정보를 나타내지 만, "크기"는 정확하게 정의 된 것이 아닙니다.

크기와 예측 가능성이 걱정된다면 8 비트 블록을 바이트로 표시하고 바이트 []로 저장하려고합니다.

1

간단히 말해서 boolean[]을 사용합니다. 또한 BitSetSet 인터페이스를 구현하지 않도록주의하십시오.

public class BitSet implements Cloneable, java.io.Serializable 
1

사용하여 그냥 아이디어, 무엇을 "에"있는 플래그의 인덱스를 HashSet 같은 것을 사용하고 추가에 대한 예, 그들이 "끈"때 그들을 제거하십시오.

(이는 대부분의 플래그가 지정된 시간에 꺼져있는 경우 특히 유용합니다).

+0

집합이 우세하게 편도이거나 다른 하나는 좋은 해결책이 될 수 있습니다. 좋은 혼합이라면, 콜렉션에서 비트 또는 부울 대신 Integer가 될 것이기 때문에 더 많은 메모리를 사용하게 될 것입니다. – digitaljoel

+0

@digitaljoel 예, 순진하게도 '32 : 1'비율과 같은 것은 "좋은"해결책이 될 것입니다. – NominSim

0

BitSet 작업이 매우 효율적이므로 the sources을 직접 검토 할 수 있습니다. 그것은 Set를 구현하지 않습니다,하지만 당신은 효과적으로처럼 간단한 사이클에서 개별 비트를 반복 할 수 있습니다

int l = bitSet.length(); 
for(int i = 0; i < l; i++) { 
    boolean bit = bitSet.get(i); 
    // ... 
} 

(다른 사람이 볼 수 있도록 귀하의 질문에 링크를 포함하십시오 BitSet1 당신이 발견`에 대한 어떤 비판? .)


당신이 관리해야하는 부울 플래그의 특정 고정 세트가있는 경우, 당신은 enum에서 해당 목록을 나열하고 EnumSet를 사용하여 플래그 설정을 나타낼 수 있습니다. 이들에 대한 작업도 매우 효율적으로 구현됩니다. 문서 인용하기 :

이 클래스의 공간 및 시간 성능은 전통적인 int 기반 "비트 플래그"대신 고품질의 유형 보증 된 대안으로 사용할 수 있도록 충분히 높아야합니다. containsAll 및 retainAll과 같은 대량 작업조차도 인수가 enum 집합 인 경우 매우 빨리 실행해야합니다. BitSet들에 비해

그리고 추가 혜택으로

,이 표현은 당신에게 문제를 많이 절약 할 수있는 type-safe이다.