2009-07-03 8 views
2

압축 할 정수가 너무 큽니다. int 배열이 먼저 자바에 의해 바이트로 변환 할 필요가Java에서 정수 배열 압축

int[] myIntArray; 
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024); 
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new DeflaterOutputStream(byteArrayOutputStream)); 
objectOutputStream.writeObject(myIntArray); 

주 -
그러나 자바에서 그것을 할 수있는 방법으로는 다음과 같이 사용하는 것입니다. 이제는 속도는 빠르지 만 완전히 새로운 바이트 배열을 만들고 전체 원래 int 배열을 스캔하여 바이트로 변환하고 새 바이트 배열에 값을 복사해야합니다.

바이트 변환을 건너 뛰고 정수를 바로 압축 할 수있는 방법이 있습니까?

+0

int 배열이 바이트로 변환되는 위치는 어디입니까? ObjectOutputStream는 객체를 가져 와서 직접 직렬화합니다. DeflaterOutputStream은 직렬화 된 결과를 압축 한 다음 압축 된 결과를 ByteArrayOutputStream에 저장합니다. 나는 그것이 정확히 당신이 원하는 것을 생각합니다 ... – Stobor

+0

제 경우에는 압축하려는 객체가 int [] 배열입니다. 직렬화 프로세스에서이를 건너 뛸 단계 인 바이트로 변환합니다. – pdeva

+0

왜? 당신은 당신이 알 필요가없는 단계를 건너 뛰고 싶다고 말합니다. 각 단계에는 데이터 복사가 있으며 압축을 풀 때도 마찬가지입니다. 실적이 문제라면 시간을 얼마나 절약하려고하십니까? 개체를 만드는 것이 적당한 양의 데이터라도 훨씬 더 비쌉니다. –

답변

4

건너 뛰고 int을 각각 byte 개로 직접 저장하십시오. 예를 들어 DataOutputStream.writeInt은 쉽게 할 수 있습니다.

2

흠. 범용 압축 알고리즘은 중복성이 많지 않은 한 이진 값 배열을 압축하는 작업을 반드시 잘 수행하지는 않습니다. 데이터에 대해 알고있는 것을 기반으로 자신 만의 무언가를 개발하는 것이 더 효과적 일 수 있습니다.

실제로 압축하려고하는 것은 무엇입니까?

2

Protocol Buffers이 사용하는 representation을 사용할 수 있습니다. 각 정수는 크기에 따라 1-5 바이트로 표시됩니다.

또한 새로운 "압축 된"표현은 기본적으로 얼마나 큰지 (그리고 어떤 필드가 있는지) 그리고 나서 데이터 만 말하는 "헤더"가 있음을 의미합니다. 그것은 아마도 ObjectOutputStream도 마찬가지입니다.하지만 PB의 최근 혁신입니다.

정수가 얼마나 자주 본지에 따라 이 아닌이 아닌 크기로 압축됩니다. 그것은 당신에게 유용 할 것인지 아닌지에 큰 영향을 줄 것입니다.

0

바이트 배열은 unsigned int를 유지하는 바이트 배열을 만들지 않는 한 많은 메모리를 절약하지 않습니다. 이는 Java에서 매우 위험합니다. 메모리 오버 헤드를 코드의 단계 확인을위한 추가 처리 시간으로 대체합니다. 이것은 데이터 저장을위한 것일 수 있지만 이미 데이터 저장 솔루션이 있습니다.
직렬화를 위해이 작업을 수행하지 않는다면 시간 낭비라고 생각합니다.

0

int 배열에 중복이없는 것이 보장되는 경우 대신 java.util.BitSet을 사용할 수 있습니다.

기본 구현은 비트 배열로, 각 비트가 BitSet에 특정 정수가 있는지 여부를 나타 내기 때문에 메모리 사용량이 매우 적어 직렬화 할 공간이 더 적습니다.

+0

하지만 bitset은 값이 0 또는 1 인 경우에만 유용하지만 uptil integer.maxvalue 범위의 값을 가지며 물론 중복되지 않습니다. – pdeva

+1

아니요, java.util.BitSet은 필요한 많은 고유 한 정수를 저장할 수 있습니다. – Reginaldo

0

예제에서 압축 된 스트림을 ByteArrayOutputStream에 쓰고 있습니다. 압축 된 배열이 어딘가에 존재해야하며 대상이 메모리 인 경우 ByteArrayOutputStream을 선택해야합니다. 스트림을 소켓이나 파일에 쓸 수도 있습니다. 이 경우 스트림을 메모리에 복제하지 않을 것입니다. 배열이 800MB이고 1GB로 실행중인 경우 포함 된 예제로 압축 파일에 배열을 쉽게 쓸 수 있습니다. 변경은 ByteArrayOutputStream을 파일 스트림으로 대체하는 것입니다.

ObjectOutputStream 형식은 실제로 상당히 효율적입니다. 그것은 배열에 메모리를 복제하지 않으며 배열을 효율적으로 작성하기위한 특별한 코드를 가지고 있습니다.

압축 된 배열을 메모리에서 사용하고 싶습니까? 데이터가 희소 배열에 적합합니까? 스파 스 배열은 데이터에 큰 차이가있을 때 좋습니다.