먼저 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 기능과 같은.. 여전히 최적화의 여지가 남아 있습니다. 더 이상 제가 갖고 있는 “자바는 느리다”라는 선입견이 상당 부분 깨진 느낌입니다.