문제

누구든지 내가 다음과 같은 일을 해야하는지 추천 할 수 있습니까?

os = new GzipOutputStream(new BufferedOutputStream(...));

또는

os = new BufferedOutputStream(new GzipOutputStream(...));

어느 것이 더 효율적입니까? BufferedOutputStream을 사용해야합니까?

도움이 되었습니까?

해결책

어떤 순서를 사용해야합니다 GzipOutputStream 그리고 BufferedOutputStream

객체 스트림의 경우 입력과 출력 모두에 대해 GZIP 스트림 주위에 버퍼링 된 스트림을 감싸는 것을 발견했습니다. 중요하게 더 빠르게. 물체가 작을수록 더 잘 했어요. 모든 경우에 더 낫거나 동일하게 버퍼링 된 스트림이 없습니다.

ois = new ObjectInputStream(new BufferedInputStream(new GZIPInputStream(fis)));
oos = new ObjectOutputStream(new BufferedOutputStream(new GZIPOutputStream(fos)));

하지만, 텍스트와 직선 바이트 스트림의 경우, 버퍼링 된 스트림 주변의 GZIP 스트림이 약간 더 좋았습니다. 그러나 모든 경우에 더 나은 경우 버퍼링 스트림이 없습니다.

reader = new InputStreamReader(new GZIPInputStream(new BufferedInputStream(fis)));
writer = new OutputStreamWriter(new GZIPOutputStream(new BufferedOutputStream(fos)));

나는 각 버전을 20 번 실행하고 첫 번째 달리기를 잘라 내고 나머지는 평균적으로 달렸다. 또한 버퍼링 Gzip- 부러를 시도했는데, 이는 물체의 경우 약간 더 좋고 텍스트에 대해 더 나빴습니다. 나는 버퍼 크기로 전혀 놀지 않았다.


객체 스트림의 경우 10 대의 메가 바이트에서 2 개의 직렬화 된 객체 파일을 테스트했습니다. 더 큰 파일 (38MB)의 경우, 읽기시 85% 빠르지 않았지만 (0.7 대 5.6 초)는 실제로 쓰기에 약간 느립니다 (5.9 대 5.7 초). 이 객체에는 큰 배열이 있었는데, 이는 더 큰 글을 의미 할 수 있습니다.

method       crc     date  time    compressed    uncompressed  ratio
defla   eb338650   May 19 16:59      14027543        38366001  63.4%

더 작은 파일 (18MB)의 경우 읽기가 75% 빠르며 (1.6 대 6.1 초), 쓰기의 경우 40% 더 빠릅니다 (2.8 대 4.7 초). 그것은 많은 작은 물체를 포함했습니다.

method       crc     date  time    compressed    uncompressed  ratio
defla   92c9d529   May 19 16:56       6676006        17890857  62.7%

텍스트 리더/작가의 경우 64MB CSV 텍스트 파일을 사용했습니다. 버퍼링 된 스트림 주변의 GZIP 스트림은 읽기가 11% 더 빠르며 (950 대 1070 밀리 초), 쓰면 (7.9 대 8.1 초) 약간 빠릅니다.

method       crc     date  time    compressed    uncompressed  ratio
defla   c6b72e34   May 20 09:16      22560860        63465800  64.5%

다른 팁

gzipoutputStream 이미 내장 버퍼가 제공됩니다. 따라서 체인 옆에 버퍼드 아웃 푸트 스트림을 바로 넣을 필요가 없습니다. Gojomo의 훌륭한 답변은 이미 버퍼를 배치 할 위치에 대한 지침을 제공합니다.

GzipoutputStream의 기본 버퍼 크기는 512 바이트이므로 생성자 매개 변수를 통해 8K 또는 64K로 늘려야합니다. BufferedOutputStream의 기본 버퍼 크기는 8K이므로 기본 gzipoutputStream과 BufferedOutputStream을 결합 할 때 이점을 측정 할 수 있습니다. GzipoutputStream의 내장 버퍼를 올바르게 크기를 조정함으로써 이러한 장점을 달성 할 수 있습니다.

따라서 귀하의 질문에 답하기 위해 : "BufferedOutputStream을 사용해야합니까?" → 아니요, 귀하의 경우 사용하지 말고 대신 GzipoutputStream의 버퍼를 최소 8K로 설정해야합니다.

버퍼링은 데이터의 궁극적 인 대상이 코드가 푸시하는 것보다 더 큰 덩어리로 가장 잘 읽거나 쓰는 경우에 도움이됩니다. 따라서 일반적으로 버퍼링이 그 장소에 가까워지기를 원합니다. 당신의 예에서, 그것은 "..."라는 장교입니다. 그래서 bufferedOutputStream을 gzipoutputStream으로 감싸십시오. 또한 버퍼드 아웃 스트림 버퍼 크기를 조정하여 테스트 쇼가 대상과 가장 잘 맞는 것과 일치합니다.

나는 외부의 버퍼드 아웃 푸트 스트림이 명시 적 버퍼링없이 많은 도움이 될지 의심합니다. 왜 안 돼? gzipoutputstream은 외부 버퍼링이 존재하는지 여부에 관계없이 동일한 크기의 덩어리에서 write () s to "..."를 수행합니다. 따라서 "..."가능성을 최적화 할 수 없습니다. 당신은 어떤 크기의 gzipoutputstream write () s에 붙어 있습니다.

또한 압축되지 않은 데이터가 아닌 압축 데이터를 버퍼링하여 메모리를보다 효율적으로 사용하고 있습니다. 데이터가 종종 6 배 압축을 겪는 경우 '내부'버퍼는 '외부'버퍼 6x와 동일합니다.

일반적으로 OS에 너무 많은 통화와 자주 디스크 액세스를 피하기 위해 파일 아웃 PutStream에 가까운 버퍼를 원합니다. 그러나 GzipoutputStream에 많은 작은 덩어리를 쓰는 경우 Gzipos 주변의 버퍼도 혜택을받을 수 있습니다. Gzipos의 쓰기 방법 인 이유는 동기화되어 있으며 다른 동기화 된 호출과 몇 개의 기본 (JNI) 호출 (CRC32를 업데이트하고 실제 압축을 수행하기 위해)으로 이어집니다. 이것들은 모두 통화 당 추가 오버 헤드를 추가합니다. 따라서이 경우 두 버퍼의 혜택을 누릴 수 있다고 말할 것입니다.

큰 파일을 압축하고 그것이 큰 차이를 만드는 데 얼마나 걸리는지 시간까지 간단한 벤치 마크를 시도하는 것이 좋습니다. GzipoutputStream에는 버퍼링이 있지만 더 작은 버퍼입니다. 나는 64K 버퍼로 첫 번째를 할 것이지만, 둘 다하는 것이 더 좋다는 것을 알 수 있습니다.

Javadoc을 읽으면 BIS가 일부 원래 소스에서 읽은 바이트를 버퍼하는 데 사용된다는 것을 알게됩니다. 원시 바이트를 얻으면 압축하려면 GIS로 BIS를 감습니다. GZIP에서 출력을 버퍼링하는 것은 의미가 없습니다. 왜냐하면 누가 그렇게 할 것인가?

new GzipInputStream( new BufferedInputStream ( new FileInputXXX
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top