成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

極端苛刻的CPU限制下仍能正常工作?Java不同壓縮算法的性能比較

開發 后端 算法
本文將會對常用的幾個壓縮算法的性能作一下比較。結果表明,某些算法在極端苛刻的CPU限制下仍能正常工作。

本文將會對常用的幾個壓縮算法的性能作一下比較。結果表明,某些算法在極端苛刻的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相比,它的壓縮的結果要略微差一點。如果想搞清楚它的工作原理,我建議你讀一下這篇文章。它是基于友好的Apache 2.0許可證發布的。
  • Snappy——這是Google開發的一個非常流行的壓縮算法,它旨在提供速度與壓縮比都相對較優的壓縮算法。我用來測試的是這個實現。它也是遵循Apache 2.0許可證發布的。

壓縮測試

要找出哪些既適合進行數據壓縮測試又存在于大多數Java開發人員的電腦中(我可不希望你為了運行這個測試還得個幾百兆的文件)的文件也著實費了我不少工夫。最后我想到,大多數人應該都會在本地安裝有JDK的文檔。因此我決定將javadoc的目錄整個合并成一個文件——拼接所有文件。這個通過tar命令可以很容易完成,但并非所有人都是Linux用戶,因此我寫了個程序來生成這個文件:

  1. public class InputGenerator { 
  2.     private static final String JAVADOC_PATH = "your_path_to_JDK/docs"
  3.     public static final File FILE_PATH = new File( "your_output_file_path" ); 
  4.   
  5.     static 
  6.     { 
  7.         try { 
  8.             if ( !FILE_PATH.exists() ) 
  9.                 makeJavadocFile(); 
  10.         } catch (IOException e) { 
  11.             e.printStackTrace(); 
  12.         } 
  13.     } 
  14.   
  15.     private static void makeJavadocFile() throws IOException { 
  16.         try( OutputStream os = new BufferedOutputStream( new FileOutputStream( FILE_PATH ), 65536 ) ) 
  17.         { 
  18.             appendDir(os, new File( JAVADOC_PATH )); 
  19.         } 
  20.         System.out.println( "Javadoc file created" ); 
  21.     } 
  22.   
  23.     private static void appendDir( final OutputStream os, final File root ) throws IOException { 
  24.         for ( File f : root.listFiles() ) 
  25.         { 
  26.             if ( f.isDirectory() ) 
  27.                 appendDir( os, f ); 
  28.             else 
  29.                 Files.copy(f.toPath(), os); 
  30.         } 
  31.     } 

在我的機器上整個文件的大小是354,509,602字節(338MB)。

測試

一開始我想把整個文件讀進內存里,然后再進行壓縮。不過結果表明這么做的話即便是4G的機器上也很容易把堆內存空間耗盡。

于是我決定使用操作系統的文件緩存。這里我們用的測試框架是JMH。這個文件在預熱階段會被操作系統加載到緩存中(在預熱階段會先壓縮兩次)。我會將內容壓縮到ByteArrayOutputStream流中(我知道這并不是最快的方法,但是對于各個測試而言它的性能是比較穩定的,并且不需要花費時間將壓縮后的數據寫入到磁盤里),因此還需要一些內存空間來存儲這個輸出結果。

下面是測試類的基類。所有的測試不同的地方都只在于壓縮的輸出流的實現不同,因此可以復用這個測試基類,只需從StreamFactory實現中生成一個流就好了:

  1. @OutputTimeUnit(TimeUnit.MILLISECONDS) 
  2. @State(Scope.Thread) 
  3. @Fork(1
  4. @Warmup(iterations = 2
  5. @Measurement(iterations = 3
  6. @BenchmarkMode(Mode.SingleShotTime) 
  7. public class TestParent { 
  8.     protected Path m_inputFile; 
  9.   
  10.     @Setup 
  11.     public void setup() 
  12.     { 
  13.         m_inputFile = InputGenerator.FILE_PATH.toPath(); 
  14.     } 
  15.   
  16.     interface StreamFactory 
  17.     { 
  18.         public OutputStream getStream( final OutputStream underlyingStream ) throws IOException; 
  19.     } 
  20.   
  21.     public int baseBenchmark( final StreamFactory factory ) throws IOException 
  22.     { 
  23.         try ( ByteArrayOutputStream bos = new ByteArrayOutputStream((int) m_inputFile.toFile().length()); 
  24.               OutputStream os = factory.getStream( bos ) ) 
  25.         { 
  26.             Files.copy(m_inputFile, os); 
  27.             os.flush(); 
  28.             return bos.size(); 
  29.         } 
  30.     } 

這些測試用例都非常相似(在文末有它們的源代碼),這里只列出了其中的一個例子——JDK deflate的測試類;

  1. public class JdkDeflateTest extends TestParent { 
  2.     @Param({"1""2""3""4""5""6""7""8""9"}) 
  3.     public int m_lvl; 
  4.   
  5.     @Benchmark 
  6.     public int deflate() throws IOException 
  7.     { 
  8.         return baseBenchmark(new StreamFactory() { 
  9.             @Override 
  10.             public OutputStream getStream(OutputStream underlyingStream) throws IOException { 
  11.                 final Deflater deflater = new Deflater( m_lvl, true ); 
  12.                 return new DeflaterOutputStream( underlyingStream, deflater, 512 ); 
  13.             } 
  14.         }); 
  15.     } 

測試結果

輸出文件的大小

首先我們來看下輸出文件的大小:

||實現||文件大小(字節)|| ||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||

可以看出文件的大小相差懸殊(從60Mb到131Mb)。我們再來看下不同的壓縮方法需要的時間是多少。

壓縮時間

||實現||壓縮時間(ms)|| ||Snappy.framedOutput ||2264.700|| ||Snappy.normalOutput ||2201.120|| ||Lz4.testFastNative ||1056.326|| ||Lz4.testFastUnsafe ||1346.835|| ||Lz4.testFastSafe ||1917.929|| ||Lz4.testHighNative ||7489.958|| ||Lz4.testHighUnsafe ||10306.973|| ||Lz4.testHighSafe ||14413.622|| ||deflate (lvl=1) ||4522.644|| ||deflate (lvl=2) ||4726.477|| ||deflate (lvl=3) ||5081.934|| ||deflate (lvl=4) ||6739.450|| ||deflate (lvl=5) ||7896.572|| ||deflate (lvl=6) ||9783.701|| ||deflate (lvl=7) ||10731.761|| ||deflate (lvl=8) ||14760.361|| ||deflate (lvl=9) ||14878.364|| ||GZIP ||10351.887||

我們再將壓縮時間和文件大小合并到一個表中來統計下算法的吞吐量,看看能得出什么結論。

吞吐量及效率

||實現||時間(ms)||未壓縮文件大小||吞吐量(Mb/秒)||壓縮后文件大小(Mb)|| ||Snappy.normalOutput ||2201.12 ||338 ||153.5581885586 ||131.8454742432|| ||Snappy.framedOutput ||2264.7 ||338 ||149.2471409017 ||96.7693328857|| ||Lz4.testFastNative ||1056.326 ||338 ||319.9769768045 ||93.7557220459|| ||Lz4.testFastSafe ||1917.929 ||338 ||176.2317583185 ||93.7557220459|| ||Lz4.testFastUnsafe ||1346.835 ||338 ||250.9587291688 ||93.7557220459|| ||Lz4.testHighNative ||7489.958 ||338 ||45.1270888301 ||78.2680511475|| ||Lz4.testHighSafe ||14413.622 ||338 ||23.4500391366 ||78.2680511475|| ||Lz4.testHighUnsafe ||10306.973 ||338 ||32.7933332124 ||78.2680511475|| ||deflate (lvl=1) ||4522.644 ||338 ||74.7350443679 ||74.7394561768|| ||deflate (lvl=2) ||4726.477 ||338 ||71.5120374012 ||71.7735290527|| ||deflate (lvl=3) ||5081.934 ||338 ||66.5101120951 ||69.8471069336|| ||deflate (lvl=4) ||6739.45 ||338 ||50.1524605124 ||64.9452209473|| ||deflate (lvl=5) ||7896.572 ||338 ||42.8033835442 ||62.6564025879|| ||deflate (lvl=6) ||9783.701 ||338 ||34.5472536415 ||61.2258911133|| ||deflate (lvl=7) ||10731.761 ||338 ||31.4952969974 ||61.0446929932|| ||deflate (lvl=8) ||14760.361 ||338 ||22.8991689295 ||60.8825683594|| ||deflate (lvl=9) ||14878.364 ||338 ||22.7175514727 ||60.8730316162|| ||GZIP ||10351.887 ||338 ||32.651051929 ||61.2258911133||

可以看到,其中大多數實現的效率是非常低的:在Xeon E5-2650處理器上,高級別的deflate大約是23Mb/秒,即使是GZIP也就只有33Mb/秒,這大概很難令人滿意。同時,最快的defalte算法大概能到75Mb/秒,Snappy是150Mb/秒,而LZ4(快速,JNI實現)能達到難以置信的320Mb/秒!

從表中可以清晰地看出目前有兩種實現比較處于劣勢:Snappy要慢于LZ4(快速壓縮),并且壓縮后的文件要更大。相反,LZ4(高壓縮比)要慢于級別1到4的deflate,而輸出文件的大小即便和級別1的deflate相比也要大上不少。

因此如果需要進行“實時壓縮”的話我肯定會在LZ4(快速)的JNI實現或者是級別1的deflate中進行選擇。當然如果你的公司不允許使用第三方庫的話你也只能使用deflate了。你還要綜合考慮有多少空閑的CPU資源以及壓縮后的數據要存儲到哪里。比方說,如果你要將壓縮后的數據存儲到HDD的話,那么上述100Mb/秒的性能對你而言是毫無幫助的(假設你的文件足夠大的話)——HDD的速度會成為瓶頸。同樣的文件如果輸出到SSD硬盤的話——即便是LZ4在它面前也顯得太慢了。如果你是要先壓縮數據再發送到網絡上的話,最好選擇LZ4,因為deflate75Mb/秒的壓縮性能跟網絡125Mb/秒的吞吐量相比真是小巫見大巫了(當然,我知道網絡流量還有包頭,不過即使算上了它這個差距也是相當可觀的)。

總結

  • 如果你認為數據壓縮非常慢的話,可以考慮下LZ4(快速)實現,它進行文本壓縮能達到大約320Mb/秒的速度——這樣的壓縮速度對大多數應用而言應該都感知不到。
  • 如果你受限于無法使用第三方庫或者只希望有一個稍微好一點的壓縮方案的話,可以考慮下使用JDK deflate(lvl=1)進行編解碼——同樣的文件它的壓縮速度能達到75Mb/秒。

源代碼

Java壓縮測試源碼

原文轉自:Java不同壓縮算法的性能比較

 
責任編輯:張偉 來源: Java驛站
相關推薦

2010-12-27 16:01:45

jQuery選擇器

2024-12-02 08:00:00

2011-04-15 10:26:38

JavaMVC

2010-03-10 16:35:23

Python編程語言

2020-07-27 08:24:42

編程語言C語言Java

2013-12-16 10:20:48

MySQL數據庫

2012-12-03 10:26:51

Scala

2016-12-07 10:42:57

排序算法實例

2009-07-01 18:12:18

JSP的優勢性能比較

2015-03-09 10:40:44

MySQL大量數據插入

2011-07-06 14:18:40

Percona SerMySQL

2015-02-05 09:25:51

HTTPSSPDYHTTP2

2015-06-17 13:58:22

Java序列化庫

2009-12-16 14:10:12

路由技術性能比較

2009-05-25 08:39:08

iPhone蘋果移動OS

2014-08-20 09:49:50

虛擬機Linux Conta

2011-05-18 14:52:04

XML

2021-01-11 14:16:19

Bean代碼Java

2011-04-28 09:49:56

SQLwith子查詢

2023-11-20 10:34:09

語言
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人av网站在线观看 | 欧美在线视频网 | 可以在线看的黄色网址 | 羞羞视频在线观看 | 365夜爽爽欧美性午夜免费视频 | 免费黄色大片 | 午夜欧美日韩 | 91久久久www播放日本观看 | 欧美日韩国产在线观看 | 久久久久久久久久性 | 国产欧美一区二区三区在线播放 | 涩涩导航| 日韩一级免费大片 | 久久久综合网 | 99热成人在线 | 日日精品 | 日本在线播放一区二区 | 欧美激情欧美激情在线五月 | 成人在线精品视频 | 天堂一区在线观看 | 国产精品1区2区 | 亚洲精品国产成人 | 成年人在线播放 | 黄色大片在线视频 | 国产一区二区激情视频 | 91麻豆精品国产91久久久久久久久 | 91婷婷韩国欧美一区二区 | 91久久久久| 久久精品视频亚洲 | 老外黄色一级片 | 国产精品亚洲一区 | 久久性 | 在线播放中文字幕 | 日本中文字幕一区 | 国产成人精品高清久久 | 国内自拍视频在线观看 | 亚洲综合大片69999 | 精品国产一区二区三区观看不卡 | 欧美精品久久久 | 免费的黄色片子 | 亚洲精品国产精品国自产在线 |