没有合适的资源?快使用搜索试试~ 我知道了~
首页通过Java测试几种压缩算法的性能(附测试代码下载)
资源详情
资源评论
资源推荐

通过通过Java测试几种压缩算法的性能(附测试代码下载)测试几种压缩算法的性能(附测试代码下载)
主要介绍了通过Java测试几种压缩算法的实际性能的一个实验,包括Java自带的deflate与GZIP压缩方式,还是有一定借鉴意义的,需要的朋友可以参考下
本文将会对常用的几个压缩算法的性能作一下比较。结果表明,某些算法在极端苛刻的CPU限制下仍能正常工作。
文中进行比较的算有:
JDK GZIP ——这是一个压缩比高的慢速算法,压缩后的数据适合长期使用。JDK中的java.util.zip.GZIPInputStream / GZIPOutputStream便是这个算法的实现。
JDK deflate ——这是JDK中的又一个算法(zip文件用的就是这一算法)。它与gzip的不同之处在于,你可以指定算法的压缩级别,这样你可以在压缩时间和输出文件大小上进行平衡。可选的级别有
0(不压缩),以及1(快速压缩)到9(慢速压缩)。它的实现是java.util.zip.DeflaterOutputStream / InflaterInputStream。
LZ4压缩算法的Java实现——这是本文介绍的算法中压缩速度最快的一个,与最快速的deflate相比,它的压缩的结果要略微差一点。
Snappy——这是Google开发的一个非常流行的压缩算法,它旨在提供速度与压缩比都相对较优的压缩算法。
压缩测试
要找出哪些既适合进行数据压缩测试又存在于大多数Java开发人员的电脑中(我可不希望你为了运行这个测试还得个几百兆的文件)的文件也着实费了我不少工夫。最后我想到,大多数人应该都会在本
地安装有JDK的文档。因此我决定将javadoc的目录整个合并成一个文件——拼接所有文件。这个通过tar命令可以很容易完成,但并非所有人都是Linux用户,因此我写了个程序来生成这个文件:
public class InputGenerator {
private static final String JAVADOC_PATH = "your_path_to_JDK/docs";
public static final File FILE_PATH = new File( "your_output_file_path" );
static
{
try {
if ( !FILE_PATH.exists() )
makeJavadocFile();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void makeJavadocFile() throws IOException {
try( OutputStream os = new BufferedOutputStream( new FileOutputStream( FILE_PATH ), 65536 ) )
{
appendDir(os, new File( JAVADOC_PATH ));
}
System.out.println( "Javadoc file created" );
}
private static void appendDir( final OutputStream os, final File root ) throws IOException {
for ( File f : root.listFiles() )
{
if ( f.isDirectory() )
appendDir( os, f );
else
Files.copy(f.toPath(), os);
}
}
}
在我的机器上整个文件的大小是354,509,602字节(338MB)。
测试测试
一开始我想把整个文件读进内存里,然后再进行压缩。不过结果表明这么做的话即便是4G的机器上也很容易把堆内存空间耗尽。
于是我决定使用操作系统的文件缓存。这里我们用的测试框架是JMH。这个文件在预热阶段会被操作系统加载到缓存中(在预热阶段会先压缩两次)。我会将内容压缩到ByteArrayOutputStream流中
(我知道这并不是最快的方法,但是对于各个测试而言它的性能是比较稳定的,并且不需要花费时间将压缩后的数据写入到磁盘里),因此还需要一些内存空间来存储这个输出结果。
下面是测试类的基类。所有的测试不同的地方都只在于压缩的输出流的实现不同,因此可以复用这个测试基类,只需从StreamFactory实现中生成一个流就好了:
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread)
@Fork(1)
@Warmup(iterations = 2)
@Measurement(iterations = 3)
@BenchmarkMode(Mode.SingleShotTime)
public class TestParent {
protected Path m_inputFile;
@Setup
public void setup()
{
m_inputFile = InputGenerator.FILE_PATH.toPath();
}
interface StreamFactory
{
public OutputStream getStream( final OutputStream underlyingStream ) throws IOException;
}
public int baseBenchmark( final StreamFactory factory ) throws IOException
{
try ( ByteArrayOutputStream bos = new ByteArrayOutputStream((int) m_inputFile.toFile().length());
OutputStream os = factory.getStream( bos ) )
{
Files.copy(m_inputFile, os);
os.flush();
return bos.size();
}
}
}
这些测试用例都非常相似(在文末有它们的源代码),这里只列出了其中的一个例子——JDK deflate的测试类;
public class JdkDeflateTest extends TestParent {
@Param({"1", "2", "3", "4", "5", "6", "7", "8", "9"})
public int m_lvl;
@Benchmark
public int deflate() throws IOException
{
return baseBenchmark(new StreamFactory() {
@Override
public OutputStream getStream(OutputStream underlyingStream) throws IOException {
final Deflater deflater = new Deflater( m_lvl, true );
return new DeflaterOutputStream( underlyingStream, deflater, 512 );
}
});
}
}
测试结果测试结果
输出文件的大小输出文件的大小
首先我们来看下输出文件的大小:
||实现||文件大小(字节)|| ||GZIP||64,200,201|| ||Snappy (normal)||138,250,196|| ||Snappy (framed)|| 101,470,113|| ||LZ4 (fast)|| 98,316,501|| ||LZ4 (high) ||82,076,909|| ||Deflate (lvl=1) ||78,369,711|| ||Deflate (lvl=2) ||75,261,711|| ||Deflate (lvl=3) ||73,240,781|| ||Deflate (lvl=4) ||68,090,059|| ||Deflate (lvl=5) ||65,699,810|| ||Deflate (lvl=6) ||64,200,191|| ||Deflate (lvl=7) ||64,013,638|| ||Deflate (lvl=8) ||63,845,758|| ||Deflate (lvl=9) ||63,839,200||















安全验证
文档复制为VIP权益,开通VIP直接复制

评论0