inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish )。
在选择压缩、打包算法的时候,不仅仅要选择算法,还需要选择用哪个实现类库,不同的实现类库实现效率不同,默认压缩比率不同。为了测试JDK、Ant、commons-compress在默认情况下的效率,设计了如下程序:
100M大小随机字符串文件生成程序:
package study.inkfish.compress; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.RandomStringUtils; public class CharFileGener { public static void main(String[] args) throws IOException { charGener(); } private static void charGener() throws IOException { Writer writer = new BufferedWriter(new FileWriter(new File("D:/TestCompress/txt.txt")), 1024 * 1024 * 5); int max = 1024 * 1024; String strs = "`1234567890-=~!@#$%^&*()_+qwertyuiop[]//QWERTYUIOP{}|asdfghjkl;'/":LKJHGFDSAzxcvbnm,./?><MNBVCXZ"; for (int i = 0; i < max; i++) { writer.write(RandomStringUtils.random(99, strs)); writer.write("/n"); } IOUtils.closeQuietly(writer); } }
上面的代码用于生成随机的半角字符组成的文本文件,大小为100M(1024*1024*100byte)。
性能测试程序:
package study.inkfish.compress; import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; public class TestCompress { public static void main(String[] args) throws IOException { File srcFile = new File("D:/TestCompress", "text.txt"); for (int i = 0; i < 3; i++) {//循环测试三遍 doTest(srcFile); cleanDir(srcFile); } } private static void cleanDir(File srcFile) throws IOException { FileUtils.deleteDirectory(new File(srcFile.getParentFile(), "jdk")); FileUtils.deleteDirectory(new File(srcFile.getParentFile(), "ant")); FileUtils.deleteDirectory(new File(srcFile.getParentFile(), "commons")); } /**测试某类库某一压缩/打包算法的压缩/打包、解压/解包*/ private static void doTest(Compress comp, File srcFile, File destFile) { try { long start = System.nanoTime(); comp.compress(srcFile, destFile); long compressTime = System.nanoTime() - start; System.out.printf("%20s,原始文件大小:%7.3fM,压缩后文件大小:%7.3fM,压缩耗时:%9.2f毫秒", comp.getClass() .getSimpleName(), toMSize(srcFile.length()), toMSize(destFile.length()), toMilliSec(compressTime)); try { start = System.nanoTime(); comp.decompress(destFile, destFile.getParentFile()); long decompressTime = System.nanoTime() - start; System.out.printf(",解压缩耗时:%9.2f毫秒,总耗时:%9.2f毫秒/n", toMilliSec(decompressTime), toMilliSec(compressTime + decompressTime)); } catch (Throwable t) { t.printStackTrace(); } } catch (Throwable t) { t.printStackTrace(); } } private static void doTest(File srcFile) { String path = srcFile.getParent(); String srcFileStr = srcFile.getName(); System.out.println("/n源文件:" + srcFile.toString()); System.out.println("/n" + StringUtils.center("压缩测试", 120, '=')); doTest(new JdkZLIBCompress(), srcFile, new File(path, "jdk/zlib/" + srcFileStr + ".zlib")); doTest(new JdkGZIPCompress(), srcFile, new File(path, "jdk/gz/" + srcFileStr + ".gz")); doTest(new CommonsGZIPCompress(), srcFile, new File(path, "commons/gzip/" + srcFileStr + ".gz")); doTest(new AntBzip2Compress(), srcFile, new File(path, "ant/bzip2/" + srcFileStr + ".bz2")); doTest(new CommonsBZip2Compress(), srcFile, new File(path, "commons/bzip2/" + srcFileStr + ".bz2")); doTest(new JdkZipCompress(), srcFile, new File(path, "jdk/zip/" + srcFileStr + ".zip")); doTest(new AntZipCompress(), srcFile, new File(path, "ant/zip/" + srcFileStr + ".zip")); doTest(new CommonsZipCompress(), srcFile, new File(path, "commons/zip/" + srcFileStr + ".zip")); System.out.println("/n" + StringUtils.center("打包测试", 120, '=')); doTest(new AntTarCompress(), srcFile, new File(path, "ant/tar/" + srcFileStr + ".tar")); doTest(new CommonsTarCompress(), srcFile, new File(path, "commons/tar/" + srcFileStr + ".tar")); doTest(new CommonsArCompress(), srcFile, new File(path, "commons/ar/" + srcFileStr + ".ar")); doTest(new CommonsCPIOCompress(), srcFile, new File(path, "commons/cipo/" + srcFileStr + ".cipo")); } /** 纳秒转毫秒 */ private static float toMilliSec(long interval) { return interval / 1000F / 1000F; } /** Byte转MByte */ private static float toMSize(long size) { return size / 1024F / 1024F; } }
测试环境:
硬件:Dell Latitude E6400(Intel Core2 Duo P8600、2G内存、7200转高速硬盘)
软件:Windows XP SP3
类库:JDK 1.6.0_11、Ant 1.7.0、commons-compress 1.0、commons-io 1.4、commons-lang 2.4
原始测试结果:
源文件:D:/TestCompress/text.txt ==========================================================压缩测试========================================================== JdkZLIBCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 14164.39毫秒,解压缩耗时: 6468.35毫秒,总耗时: 20632.74毫秒 JdkGZIPCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10681.97毫秒,解压缩耗时: 6824.98毫秒,总耗时: 17506.95毫秒 CommonsGZIPCompress,原始文件大小:100.000M,压缩后文件大小: 82.999M,压缩耗时: 35713.27毫秒,解压缩耗时: 28766.85毫秒,总耗时: 64480.12毫秒 AntBzip2Compress,原始文件大小:100.000M,压缩后文件大小: 82.999M,压缩耗时: 35838.90毫秒,解压缩耗时: 28093.38毫秒,总耗时: 63932.28毫秒 CommonsBZip2Compress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时:113749.55毫秒,解压缩耗时:104879.45毫秒,总耗时:218628.98毫秒 JdkZipCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10624.03毫秒,解压缩耗时: 6529.68毫秒,总耗时: 17153.71毫秒 AntZipCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10579.43毫秒,解压缩耗时: 10021.43毫秒,总耗时: 20600.86毫秒 CommonsZipCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10323.45毫秒,解压缩耗时: 6798.18毫秒,总耗时: 17121.63毫秒 ==========================================================打包测试========================================================== AntTarCompress,原始文件大小:100.000M,压缩后文件大小:100.010M,压缩耗时: 6464.60毫秒,解压缩耗时: 3999.30毫秒,总耗时: 10463.90毫秒 CommonsTarCompress,原始文件大小:100.000M,压缩后文件大小:100.010M,压缩耗时: 5286.30毫秒,解压缩耗时: 6248.18毫秒,总耗时: 11534.47毫秒 CommonsArCompress,原始文件大小:100.000M,压缩后文件大小:100.000M,压缩耗时: 5986.99毫秒,解压缩耗时: 5614.21毫秒,总耗时: 11601.19毫秒 CommonsCPIOCompress,原始文件大小:100.000M,压缩后文件大小:100.000M,压缩耗时: 6812.78毫秒,解压缩耗时: 5749.83毫秒,总耗时: 12562.61毫秒 源文件:D:/TestCompress/text.txt ==========================================================压缩测试========================================================== JdkZLIBCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10820.10毫秒,解压缩耗时: 6837.67毫秒,总耗时: 17657.77毫秒 JdkGZIPCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10742.54毫秒,解压缩耗时: 6471.39毫秒,总耗时: 17213.93毫秒 CommonsGZIPCompress,原始文件大小:100.000M,压缩后文件大小: 82.999M,压缩耗时: 35621.16毫秒,解压缩耗时: 27691.03毫秒,总耗时: 63312.19毫秒 AntBzip2Compress,原始文件大小:100.000M,压缩后文件大小: 82.999M,压缩耗时: 35927.41毫秒,解压缩耗时: 27545.73毫秒,总耗时: 63473.14毫秒 CommonsBZip2Compress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时:113363.30毫秒,解压缩耗时:105609.01毫秒,总耗时:218972.30毫秒 JdkZipCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10558.16毫秒,解压缩耗时: 6784.21毫秒,总耗时: 17342.37毫秒 AntZipCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10506.37毫秒,解压缩耗时: 10327.44毫秒,总耗时: 20833.80毫秒 CommonsZipCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10399.44毫秒,解压缩耗时: 6876.46毫秒,总耗时: 17275.90毫秒 ==========================================================打包测试========================================================== AntTarCompress,原始文件大小:100.000M,压缩后文件大小:100.010M,压缩耗时: 6107.04毫秒,解压缩耗时: 4393.18毫秒,总耗时: 10500.21毫秒 CommonsTarCompress,原始文件大小:100.000M,压缩后文件大小:100.010M,压缩耗时: 5782.27毫秒,解压缩耗时: 5303.96毫秒,总耗时: 11086.22毫秒 CommonsArCompress,原始文件大小:100.000M,压缩后文件大小:100.000M,压缩耗时: 5771.36毫秒,解压缩耗时: 5549.45毫秒,总耗时: 11320.82毫秒 CommonsCPIOCompress,原始文件大小:100.000M,压缩后文件大小:100.000M,压缩耗时: 6944.52毫秒,解压缩耗时: 6227.69毫秒,总耗时: 13172.21毫秒 源文件:D:/TestCompress/text.txt ==========================================================压缩测试========================================================== JdkZLIBCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10738.53毫秒,解压缩耗时: 8055.89毫秒,总耗时: 18794.42毫秒 JdkGZIPCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10766.80毫秒,解压缩耗时: 6851.34毫秒,总耗时: 17618.14毫秒 CommonsGZIPCompress,原始文件大小:100.000M,压缩后文件大小: 82.999M,压缩耗时: 35744.91毫秒,解压缩耗时: 27782.01毫秒,总耗时: 63526.93毫秒 AntBzip2Compress,原始文件大小:100.000M,压缩后文件大小: 82.999M,压缩耗时: 35688.23毫秒,解压缩耗时: 27674.49毫秒,总耗时: 63362.73毫秒 CommonsBZip2Compress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时:114151.34毫秒,解压缩耗时:103659.39毫秒,总耗时:217810.73毫秒 JdkZipCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10754.72毫秒,解压缩耗时: 6681.37毫秒,总耗时: 17436.09毫秒 AntZipCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10437.32毫秒,解压缩耗时: 10181.76毫秒,总耗时: 20619.08毫秒 CommonsZipCompress,原始文件大小:100.000M,压缩后文件大小: 83.213M,压缩耗时: 10631.77毫秒,解压缩耗时: 6132.21毫秒,总耗时: 16763.98毫秒 ==========================================================打包测试========================================================== AntTarCompress,原始文件大小:100.000M,压缩后文件大小:100.010M,压缩耗时: 4665.05毫秒,解压缩耗时: 4996.47毫秒,总耗时: 9661.53毫秒 CommonsTarCompress,原始文件大小:100.000M,压缩后文件大小:100.010M,压缩耗时: 5434.97毫秒,解压缩耗时: 5869.99毫秒,总耗时: 11304.96毫秒 CommonsArCompress,原始文件大小:100.000M,压缩后文件大小:100.000M,压缩耗时: 6556.45毫秒,解压缩耗时: 6196.02毫秒,总耗时: 12752.47毫秒 CommonsCPIOCompress,原始文件大小:100.000M,压缩后文件大小:100.000M,压缩耗时: 6152.87毫秒,解压缩耗时: 7070.35毫秒,总耗时: 13223.22毫秒
整理后测试结果:
实现类 | 原始文件大小 | 压缩后文件大小 | 压缩耗平均时 | 解压缩平均耗时 | 平均总耗时 |
CommonsZipCompress | 100 | 83.213 | 10451.55 | 6602.28 | 17053.84 |
JdkZipCompress | 100 | 83.213 | 10645.64 | 6665.09 | 17310.72 |
JdkGZIPCompress | 100 | 83.213 | 10730.44 | 6715.90 | 17446.34 |
JdkZLIBCompress | 100 | 83.213 | 11907.67 | 7120.64 | 19028.31 |
AntZipCompress | 100 | 83.213 | 10507.71 | 10176.88 | 20684.58 |
AntBzip2Compress | 100 | 82.999 | 35818.18 | 27771.20 | 63589.38 |
CommonsGZIPCompress | 100 | 82.999 | 35693.11 | 28079.96 | 63773.08 |
CommonsBZip2Compress | 100 | 83.213 | 113754.73 | 104715.95 | 218470.67 |
实现类 | 原始文件大小 | 压包后文件大小 | 打包耗平均时 | 解包平均耗时 | 平均总耗时 |
AntTarCompress | 100 | 100.010 | 5745.56 | 4462.98 | 10208.55 |
CommonsTarCompress | 100 | 100.010 | 5501.18 | 5807.38 | 11308.55 |
CommonsArCompress | 100 | 100.000 | 6104.93 | 5786.56 | 11891.49 |
CommonsCPIOCompress | 100 | 100.000 | 6636.72 | 6349.29 | 12986.01 |
结论:
1.在各自默认压缩率下,commons-compress包中zip算法具有较快的压缩速度,ant包中tar具有较快的打包速度;
2.commons-compress中的gzip压缩速度远远慢于jdk中的gzip,虽然压缩率比jdk高;
3.ant包中bzip2因为压缩正确性有问题,得到的数据不具有可比性。
4.由于被压缩文件内容由程序自动随机生成,在应用的具体环境中,压缩率、压缩时间肯定有所不同。这里提供的源码特别是测试程序经修改能够针对具体文件进行测试,可以稍微弥补一些不足。
5.因为测试目的原因,不对压缩率进行评价。