Java와 C의 zip 압축 연산에 대한 퍼포먼스 비교

먼저 C의 zip 압축은 Jean-loup Gailly님이 만들어 공개한 zlib 1.2.2를 사용했습니다. C/C++에서 데이터의 압축에서 사용하는 압축 라이브러리는 흔히 이 zlib를 사용합니다.  그리고 Java에서 압축은 기본적으로 제공하는 java.util.zip.Deflater 클래스를 사용했습니다. 테스트를 한 이유는 Java가 C/C++에 비해서 얼마나 느릴까… 하는 기대였습니다. =_=;

Java와 C/C++ 모두 사용한 압축 데이터는 0.2메가 정도되는 jpg 파일로 했습니다. 그리고 Java와 C/C++ 모두 결과는 압축 레벨을 3으로 했을때 동일한 결과와 크기였으며 원본 크기에 비해 75% 정도의 압축되었습니다. 결과는 다음 같습니다. 첫번째 이미지는 Java의 결과이고.. 두번째는 C/C++의 결과입니다.

사용자 삽입 이미지
와우!! Java가 C/C++에 비해 상당히 느릴것으로 기대했는데… 그렇지 않았습니다. C/C++와 성능은 거의 비슷한 것으로 생각됩니다. 두 경우 모두 최악의 경우 0.016초정도 소요됩니다. 다만…. Java의 경우 가끔씩 튀는 부분이 있었는데.. 0.031초 정도 소요되는 부분이 가끔 나옵니다. 아마도 Java의 gc기능 때문이 아닌가… 가볍게 짐작해봅니다. 하지만 이런 부분은 제외하면 정말 C/C++과 같은 Native 컴파일러 못지 않은 성능이라고 판단됩니다.

아래는 Java에서 퍼포먼스 테스트로 사용했던 코드입니다.

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import java.io.*;

public class TestMain {
    public static void main(String[] args) 
        throws IOException, DataFormatException
    {
        FileInputStream fis = new FileInputStream("d:/a.jpg");
        ByteArrayOutputStream baos = new ByteArrayOutputStream(fis.available());
        byte [] buffer = new byte[512];
        int cntRead;
        while((cntRead=fis.read(buffer)) != -1) {
            baos.write(buffer, 0, cntRead);
        }

        byte[] compressedBytes = null;
        for(int i=0; i<20; i++) { // 20 times repeat..
            System.out.println("Performance Test Start...");
            long stime = System.currentTimeMillis();
 
            compressedBytes = Compress(baos.toByteArray());
   
            long etime = System.currentTimeMillis();
            System.out.println("Performance Test Result : " 
                + (etime-stime)+" MS.");
        }   
 
         FileOutputStream fos = new FileOutputStream("d:/a_java.jpg.zip");
         ByteArrayInputStream bais = new ByteArrayInputStream(compressedBytes);
         while((cntRead=bais.read(buffer)) != -1) {
             fos.write(buffer, 0, cntRead);
         }
    }

    private static byte[] Compress(byte[] bytesToCompress) throws IOException
    {
        Deflater compressor = new Deflater(3);
        compressor.setInput(bytesToCompress);
        compressor.finish();
 
        ByteArrayOutputStream bos = 
            new ByteArrayOutputStream(bytesToCompress.length);
 
        byte[] buf = new byte[bytesToCompress.length + 100];
        while (!compressor.finished())
        {
            bos.write(buf, 0, compressor.deflate(buf));
        }

        bos.close();
 
        return bos.toByteArray();
    }
}

대략 살펴보시면 위의 코드에는 IO에 대한 Buffer 기능과 같은.. 여전히 최적화의 여지가 남아 있습니다. 더 이상 제가 갖고 있는 “자바는 느리다”라는 선입견이 상당 부분 깨진 느낌입니다.

텍스트 효과 단위기능 테스트

구글맵이나 네이버지도, 다음지도 등등 모든 포털 지도사이트에서 제공하는 지도 서비스는 지도 이미지를 256×256 픽셀 크기로 잘려진 타일이미지 형태로 서비스되고 있습니다. 자사만의 지도 타일이미지 렌더링 프로그램을 직접 개발한 곳도 있을테고…. 구글처럼 오픈소스 라이브러리를 이용해 구축한 곳도 있을테고….

현재  RIA 기반의 지도 솔루션 개발에 필요한 지도 타일 이미지 렌더러를 개발하고 있습니다. 오픈소스를 활용하여 개발할까… 생각도 해보았지만… 다양한 사용자가 원하는 자신만의 지도 스타일의 충족이라는 틈새 시장을 놓고 볼때… 오픈소스의 획일화된 지도 이미지 스타일은 제 기획 의도와 맞지 않다고 판단하여 직접 개발하기로 결정하게 되었습니다.

사용자 삽입 이미지
위의 결과 이미지는 현재 개발중인 지도 타일이미지 렌더러에서 텍스트 표현을 위해 고민해본 텍스트 효과입니다. 실제 종이 지도를 살펴보고 글자에 적용된 효과를 살펴보면서 위의 3가지 효과정도면 될듯하여 하나 하나 구현해 보았습니다.

추후 타일 이미지 렌더러… 개발이 완료되면 위의 텍스트 효과가 적용된 지도를 통해 좀더 분명한 결과를 알릴 수 있겠지만.. 지금 단계에서 현재 제 스스로가 무엇을 하고 있는지… 어느 방향으로 가고 있는지에 대해 한 조각이라도 구체화하기 위한 과정으로써의 글을 올려봅니다.