在Java中快速压缩?
有一个非常快的Java压缩库吗? 标准的gzip库比我想要的要慢。 我正在寻找类似http://www.oberhumer.com/opensource/lzo/的东西,这是本地Java代码,提供快速压缩和解压缩。 谢谢!
其他一些快速压缩库供将来参考:
QuickLZ – C / C#/ Java – GPL或商业http://www.quicklz.com/
libLZF – C – BSD格式的许可证http://oldhome.schmorp.de/marc/liblzf.html
FastLZ – C – MIT风格许可证http://fastlz.org/
LZO C – GPL或商业版http://www.oberhumer.com/opensource/lzo/
zlib – C / Java(GZIP和deflate) – 商业友好的许可http://zlib.net/
Hadoop-LZO集成(JNI): http : //github.com/kevinweil/hadoop-lzo
Snappy-Java(JNI): https : //github.com/xerial/snappy-java
QuickLZ人的基准: http ://www.quicklz.com/bench.html
你可以使用DeflatorOutputStream和InflatorInputStream。 这两个都使用LZW压缩。 你可以使用他们提供的库。
编辑:实时性能通常衡量的延迟方面,但是你引用数字通过吞吐量。 你能否实时澄清你的意思?
对于延迟,使用BEST_SPEED,每次调用平均需要220 ns + 13 ns /字节。
注意:在低延迟的情况下,当CPU运行“热”时,经常会获得许多倍。 你已经在现实的情况下执行时间。
编辑:这是我得到的Java 6更新21的压缩率;
Raw OutputStream.write() - 2485 MB/sec Deflator.NO_COMPRESSION - 99 MB/s Deflator.BEST_SPEED - 85 MB/s. Deflator.FILTERED - 77 MB/s Deflator.HUFFMAN_ONLY - 79 MB/s Deflator.DEFAULT_COMPRESSION - 30 MB/s Deflator.BEST_COMPRESSION - 14 MB/s
注意:我不确定为什么默认设置比“最佳速度”设置更快。 我只能假设前者已被优化。
输出缓冲区的大小是4KB,你可能会发现不同的大小是最适合你的。
编辑:下面的代码打印一个大的CSV文件。 等待时间是5KB块。
Average latency 48532 ns. Bandwidth 91.0 MB/s. Average latency 52560 ns. Bandwidth 83.0 MB/s. Average latency 47602 ns. Bandwidth 93.0 MB/s. Average latency 51099 ns. Bandwidth 86.0 MB/s. Average latency 47695 ns. Bandwidth 93.0 MB/s.
。
public class Main { public static void main(String... args) throws IOException { final String filename = args[0]; final File file = new File(filename); DataInputStream dis = new DataInputStream(new FileInputStream(file)); byte[] bytes = new byte[(int) file.length()]; dis.readFully(bytes); test(bytes, false); for (int i = 0; i < 5; i++) test(bytes, true); } private static void test(byte[] bytes, boolean print) throws IOException { OutputStream out = new ByteOutputStream(bytes.length); Deflater def = new Deflater(Deflator.BEST_SPEED); DeflaterOutputStream dos = new DeflaterOutputStream(out, def, 4 * 1024); long start = System.nanoTime(); int count = 0; int size = 5 * 1024; for (int i = 0; i < bytes.length - size; i += size, count++) { dos.write(bytes, i, size); dos.flush(); } dos.close(); long time = System.nanoTime() - start; long latency = time / count; // 1 byte per ns = 1000 MB/s. long bandwidth = (count * size * 1000L) / time; if (print) System.out.println("Average latency " + latency + " ns. Bandwidth " + bandwidth + " MB/s."); } }
越来越好:github上有一个快速纯Java版本的Snappy 。 它是目前最快的纯Java编解码器,也可能是来自Java甚至包括C编解码器的最快的编解码器(因为速度接近通过JNI访问的本地Snappy编解码器)。
所以有三个快速的Java解压缩程序:Snappy, LZF和LZ4 (请参阅https://github.com/ning/jvm-compressor-benchmark )了解详细信息
编辑(2013年8月):LZ4是目前最快的编解码器; Snappy和LZF分享第二个插槽。 过去一年左右都取得了很好的进展,明显快于GZIP。
多一个; https://github.com/ning/compress是一个非常高效的(基于Java优化的基准testing)LZF实现。; 比放气(gzip)快2倍左右; 和更快的压缩(3倍 – 5倍)。 压缩率较低,因为它只是放气的第一部分(Lempel-Ziv),没有第二部分(哈夫曼编码); 这解释了大部分的速度差异。
按照JVM压缩机基准testing的数字: https : //github.com/ning/jvm-compressor-benchmark
LZ4和Snappy的最快纯Java实现在这里: https : //code.google.com/p/kanzi/有一个页面比较不同java实现的性能: https : //code.google.com/p / kanzi / wiki / SnappyCodec 。 LZ4速度更快,压缩比更高(通常情况下)的边距更小。
我发现使用LZ4( net.jpountz.lz4的lz4-1.2.0.jar )的解压缩时间比使用GZIPInputStream的解压缩时间快了60倍。 但压缩的大小是接近(lz的压缩大小大约6%)。
这里是各种版本的解压缩时间,在多个代表平均。 每个rep将一个压缩的字节数组解压缩1000次。
> 0.01 milliseconds for lz4 (native instance), > 0.03 milliseconds for lz4 (safe instance) > 0.05 milliseconds for lz4 (unsafe instance) > 0.05 milliseconds for lz4 ("fastest" instance) > 0.05 milliseconds for lz4 ("fastest Java" instance) > 0.74 milliseconds for gzip (GZIPInputStream)