2014-07-24 2 views
4

내가 C로 전환하여 처음 Java로 작성된 나의 TIFF 인코더 속도를 높이기 위해 노력하고있어 및 Z_SOLO 정의와 C 파일의 최소 세트 Zlib 1.2.8을 컴파일 한 대 : adler32.c, crc32.c, deflate.c, trees.czutil.c. 자바는 java.util.zip.Deflater을 사용하고 있습니다.벤치마킹 Zlib의 자바 C

필자는 압축 수준과 속도 측면에서 성능을 평가하는 간단한 테스트 프로그램을 작성했으며 수준이 필요한 모든 수준에서 더 높은 수준의 시간이 요구됨에 따라 압축이 그다지 효과적이지 못하다는 사실에 의아해했습니다. .

자바 :

Level 1 : 8424865 => 6215200 (73,8%) in 247 cycles. 
Level 2 : 8424865 => 6178098 (73,3%) in 254 cycles. 
Level 3 : 8424865 => 6181716 (73,4%) in 269 cycles. 
Level 4 : 8424865 => 6337236 (75,2%) in 334 cycles. 
Level 5 : 8424865 => 6331902 (75,2%) in 376 cycles. 
Level 6 : 8424865 => 6333914 (75,2%) in 395 cycles. 
Level 7 : 8424865 => 6333350 (75,2%) in 400 cycles. 
Level 8 : 8424865 => 6331986 (75,2%) in 437 cycles. 
Level 9 : 8424865 => 6331598 (75,2%) in 533 cycles. 

C :

Level 1 : 8424865 => 6215586 (73.8%) in 298 cycles. 
Level 2 : 8424865 => 6195280 (73.5%) in 309 cycles. 
Level 3 : 8424865 => 6182748 (73.4%) in 331 cycles. 
Level 4 : 8424865 => 6337942 (75.2%) in 406 cycles. 
Level 5 : 8424865 => 6339203 (75.2%) in 457 cycles. 
Level 6 : 8424865 => 6337100 (75.2%) in 481 cycles. 
Level 7 : 8424865 => 6336396 (75.2%) in 492 cycles. 
Level 8 : 8424865 => 6334293 (75.2%) in 547 cycles. 
Level 9 : 8424865 => 6333084 (75.2%) in 688 cycles. 

오전 나는 또한 자바는 실제로 모두 압축 속도가 Visual Studio를 출시 컴파일 (VC2010)보다 더 나은 수행하여 깜짝 놀라게했다 나는 그러한 결과를 목격 한 유일한 사람인가? 내 생각 엔 JVM의 Zlib가 C 프로젝트에 포함되지 않은 어셈블리 유형 최적화를 사용하고 있거나 Zlib (또는 Visual Studio 컴파일러가 빠져 있음)을 컴파일 할 때 확실한 구성 단계가 누락되었습니다.

자바 :

public static void main(String[] args) throws IOException { 
    byte[] pix = Files.readAllBytes(Paths.get("MY_MOSTLY_UNCOMPRESSED.TIFF")); 
    int szin = pix.length; 
    byte[] buf = new byte[szin*101/100]; 
    int szout; 
    long t0, t1; 

    for (int i = 1; i <= 9; i++) { 
     t0 = System.currentTimeMillis(); 
     Deflater deflater = new Deflater(i); 
     deflater.setInput(pix); 
     szout = deflater.deflate(buf); 
     deflater.finish(); 
     t1 = System.currentTimeMillis(); 
     System.out.println(String.format("Level %d : %d => %d (%.1f%%) in %d cycles.", i, szin, szout, 100.0f*szout/szin, t1 - t0)); 
    } 
} 

C :

#include <time.h> 
#define SZIN 9000000 
#define SZOUT 10000000 
void main(void) 
{ 
    static unsigned char buf[SZIN]; 
    static unsigned char out[SZOUT]; 
    clock_t t0, t1; 
    int i, ret; 
    uLongf sz, szin; 
    FILE* f = fopen("MY_MOSTLY_UNCOMPRESSED.TIFF", "rb"); 
    szin = fread(buf, 1, SZIN, f); 
    fclose(f); 

    for (i = 1; i <= 9; i++) { 
     sz = SZOUT; 
     t0 = clock(); 
     compress2(out, &sz, buf, szin, i); // I rewrote compress2, as it's not available when Z_SOLO is defined 
     t1 = clock(); 
     printf("Level %d : %d => %d (%.1f%%) in %ld cycles.\n", i, szin, sz, 100.0f*sz/szin, t1 - t0); 
    } 
} 

편집 : @ MarkAdler의 발언 후, 나는 deflateInit2()을 통해 서로 다른 압축 전략을 시도

(여기

두 조각입니다 즉 Z_FILTEREDZ_HUFFMAN_ONLY) :

Z_FILTERED :

Level 1 : 8424865 => 6215586 (73.8%) in 299 cycles. 
Level 2 : 8424865 => 6195280 (73.5%) in 310 cycles. 
Level 3 : 8424865 => 6182748 (73.4%) in 330 cycles. 
Level 4 : 8424865 => 6623409 (78.6%) in 471 cycles. 
Level 5 : 8424865 => 6604616 (78.4%) in 501 cycles. 
Level 6 : 8424865 => 6595698 (78.3%) in 528 cycles. 
Level 7 : 8424865 => 6594845 (78.3%) in 536 cycles. 
Level 8 : 8424865 => 6592863 (78.3%) in 595 cycles. 
Level 9 : 8424865 => 6591118 (78.2%) in 741 cycles. 

Z_HUFFMAN_ONLY : 자신의 의견에 따라 예상대로

Level 1 : 8424865 => 6803043 (80.7%) in 111 cycles. 
Level 2 : 8424865 => 6803043 (80.7%) in 108 cycles. 
Level 3 : 8424865 => 6803043 (80.7%) in 106 cycles. 
Level 4 : 8424865 => 6803043 (80.7%) in 106 cycles. 
Level 5 : 8424865 => 6803043 (80.7%) in 107 cycles. 
Level 6 : 8424865 => 6803043 (80.7%) in 106 cycles. 
Level 7 : 8424865 => 6803043 (80.7%) in 107 cycles. 
Level 8 : 8424865 => 6803043 (80.7%) in 108 cycles. 
Level 9 : 8424865 => 6803043 (80.7%) in 107 cycles. 

, Z_HUFFMAN_ONLY 압축을 변경하지만 많은 빠른 수행하지 않습니다. 내 데이터로 Z_FILTEREDZ_DEFAULT_STRATEGY보다 빠르지 않고 약간 악화되었습니다.

+0

레벨 '3'이 가장 작습니다. 당신의 데이터에 이상한 것이 없다고 확신합니까? –

+0

@PeterLawrey 2 페이지를 포함하는 "표준"TIFF 파일 크기 2800x2900입니다. 첫 번째는 압축 해제되고 두 번째는 압축 압축됩니다. 압축 된 데이터를 압축하는 것으로 이해할 수 있습니다. 이미 압축 된 데이터를 압축하려고 시도 할 수 있습니다. 무슨 일이 일어나고 있는지 봅니다 (이번 주말에 약간의 시간이 있다면). – Matthieu

+1

Java 프로그램에서'fis.read (pix)'는 전체 파일을 읽을 수 없다는 것을 알아 두십시오.이 경우'pix '의 나머지는 0이됩니다. 필자는 FileInputStream의 사용을'pix = Files.readAllBytes (Paths.get ("MY_MOSTLY_UNCOMPRESSED.TIFF"))'로 바꾸는 것이 좋습니다. – VGR

답변

3

기본적으로 일치하는 문자열이없는 압축되지 않은 이미지 데이터의 경우 압축량과 델타가 놀라운 것은 아닙니다. 압축 된 데이터의 일부는 더 압축되지 않습니다. 일부 일정한 양만큼 약간 확장되므로 변형은 모두 압축되지 않은 부분에 있습니다.

레벨 3과 4 사이의 알고리즘이 변경되었습니다. 레벨 3은 발견 된 첫 번째 일치에 대해 진행됩니다. 일치하는 문자열이 거의 없으면 문자열 일치 전송의 오버 헤드를 최소화하는 경향이 있으므로 압축률이 높아집니다. FILTERED 또는 HUFFMAN_ONLY을 사용하여 문자열 일치가 완전히 해제 된 경우 더 잘 수행 할 수 있습니다. HUFFMAN_ONLY도 일치하는 문자열을 찾지 않아도되므로 압축 속도가 크게 향상됩니다.

속도 차이에 관해서, 나는 다른 컴파일러 또는 다른 컴파일러 최적화가 사용되었다고 추측 할 수 있습니다.

+0

은 HUFMAN_ONLY도 자바에서 설정할 수 있습니까? – AlexWien

+1

'HUFFMAN_ONLY'은 사실'setStrategy'의 자바 옵션입니다. zlib에서는'Z_HUFFMAN'이라고 불립니다. –

+0

감사합니다. 그 이유가 설명됩니다. 시간이 좀 있으면 FILTERED 및 HUFFMAN_ONLY로 시도하고 결과를 게시 할 것입니다. – Matthieu