中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java性能優化中如何進行壓縮

發布時間:2021-10-20 09:24:39 來源:億速云 閱讀:198 作者:柒染 欄目:大數據

Java性能優化中如何進行壓縮,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

 壓縮

在微服務調用,如果需要傳入的內容過長,壓縮是個不錯的辦法,能提高傳輸的速度。壓縮有很多方法,一種方法是在傳輸對象的屬性名字上做調整,盡量減少傳輸報文大小,這比較適合傳輸的是JSON或者XML,比如

public class OrderRequest{
  private String orderId;
  private String userId;

}

如果使用JSON傳輸,內容是

{"orderId":xxx,"userId":yyyyy}

可以調整為

public class OrderRequest{
  private String oid;
  private String uid;
}

使用JSON傳輸 {"oid":xxx,"uid":yyyyy},這種調整,顯然傳輸報文大小體積小一點。也可以對傳輸對象的一些字段做合并,比如“訂單狀態“,"用戶狀態","測試訂單"合并成一個int類型,通過“位“來區分狀態

public class OrderRequest{
  //用戶狀態
  private int userStatus;
  //訂單狀態
  private int orderStatus;
  //測試訂單
  private int testFlag
}

改成如下,需要通過位運算獲取訂單的各個狀態

public class OrderRequest {
	/**
	 * 0位表示是否測試訂單,1-4位節表示用戶狀態,5-8位表示訂單狀態
	 */
	int s;

  public boolean isTest(){
		//取出第1位的值
		return (status&0b1)==1;
	}

	public int getUserStatus(){
		// 右移1,取出1-4位的值
		return (status>>1&0b1111);
	}

	public int getOrderStatus(){
		//右移5,取出5-8位的值
		return (status>>5&0b1111);
	}
}

這樣,OrderRequest本來需要3個int類型,總計12個字節來保存的訂單狀態,現在只需要4個字節保存即可。如果有更多的狀態,也可以用s值的剩下的位來表示。比如,訂單新增一個狀態表示是否是包含大件,可以用第9位表示

public boolean isLargeProduct(){
   return (status>>9&0b1)==1;
}

如果s值是0b1_0100_0110_1(對應的10進制653),那么isTest返回true,getUerStatus返回6,getOrderStatus返回4,isLargeProduct返回true

還有一種壓縮方法是在傳輸協議上進行壓縮,比如JSON就比XML更加節省,使用MessagePack又比JSON更加節省空間,關于MessagePack用法,會在第5章用一節詳細介紹。

在傳輸內容過多的時候,可以考慮對內容進行壓縮,對內容進行壓縮再傳送有如下好處

  • 壓縮后減少網絡傳送的字節,節約了帶寬,網絡可以同時傳送的內容更多了

  • 相比于壓縮耗時,網絡傳送更加耗時。尤其是現在的分布式系統,服務器非常便宜,可以無限擴展,從數十臺服務器到數萬臺服務都可以,然而帶寬有限且價格不菲,有些企業專網帶寬只有1M,非常小。

壓縮有各種算法,會輸出不同的壓縮比的內容,以及壓縮耗時也不一樣,本節選取zip,針對5K,20K,100k的做一個性能測試。一般來說,壓縮比越大,越耗時。在實際分布式系統調用,需要根據業務需求,確定采用什么樣的壓縮算法。

壓縮會使用JDK自帶的zip包中的Deflater類進行壓縮,提供了最快壓縮BEST_SPEED(值是1),最大壓縮比BEST_COMPRESSION(值是9),還有默認壓縮DEFAULT_COMPRESSION(值是-1)

//ZipUtil.java
public static byte[] zip(byte[] bs) throws IOException {
  return compress(bs,DEFAULT_COMPRESSION);
}
public static byte[] compress(byte[] input, int compressionLevel
			) throws IOException {
		//zip壓縮
		Deflater compressor = new Deflater(compressionLevel, false);
		//壓縮內容
		compressor.setInput(input
		//壓縮結束
		compressor.finish();
		//獲取壓縮內容
		ByteArrayOutputStream bao = new ByteArrayOutputStream();
		//一個緩沖
		byte[] readBuffer = new byte[1024];
		int readCount = 0;
		//如果壓縮內容,則循環
		while (!compressor.finished()) {
			readCount = compressor.deflate(readBuffer);
			if (readCount > 0) {
				bao.write(readBuffer, 0, readCount);
			}
		}

		compressor.end();
		return bao.toByteArray();
	}

可以測試一個100k報文,對于三種壓縮比,有如下數據,說明ZIP的默認壓縮級別已經足夠好 DEFAULT_COMPRESSION 壓縮后是34.8K BEST_SPEED 壓縮是39K BEST_COMPRESSION 壓縮后是34.7K

為了測試壓縮性能,通過Content工具類分別生成5K,20K,100K報文供測試,并且分別測試默認壓縮,最快壓縮和最好壓縮。

// ZipTest.java
byte[] k5 = null;
byte[] k20 = null;
byte[] k100 = null;
//默認,最快,最好壓縮
@Param({"-1", "1", "9"})
int level;

@Setup
public void init() {
  Content content = new Content();
  this.k5 = content.genContentBySize(1000 * 5);
  this.k20 = content.genContentBySize(1000 * 20);
  this.k100 = content.genContentBySize(1000 * 100);
}


@Benchmark
public byte[] k5() throws IOException {
  return ZipUtil.compress(k5, level);
}

@Benchmark
public byte[] k20() throws IOException {
  return ZipUtil.compress(k20, level);
}

@Benchmark
public byte[] k100() throws IOException {
  return ZipUtil.compress(k100, level);
}

JMH測試結果如下。可以看到即使20K報文內容,壓縮的速度還是非常快的。在不到1毫秒。100K報文,則需要較長時間,默認壓縮(-1)需要4毫秒左右。

Benchmark               (level)    Score  Score error  Units    
c.i.c.c.ZipTest.k100         -1    4.467        0.233  ms/op    
c.i.c.c.ZipTest.k100          1    1.773        0.097  ms/op    
c.i.c.c.ZipTest.k100          9    5.028        0.152  ms/op    
c.i.c.c.ZipTest.k20          -1    0.571        0.016  ms/op    
c.i.c.c.ZipTest.k20           1    0.310        0.010  ms/op    
c.i.c.c.ZipTest.k20           9    0.592        0.023  ms/op    
c.i.c.c.ZipTest.k5           -1    0.157        0.008  ms/op    
c.i.c.c.ZipTest.k5            1    0.112        0.005  ms/op    
c.i.c.c.ZipTest.k5            9    0.151        0.003  ms/op

這個測試選用的是一篇文章作為壓縮內容,你需要根據你的業務情況,用真實的報文來做壓縮測試,事實上,如果是XML或者JSON報文,有著非常大的壓縮比。

本節選擇了zip壓縮方式,還有其他可選方式,比如gzip,bzip2,7z等等,可以使用開源庫Apache Commons Compress進行壓縮,在筆者測試后,發現zip還是一種壓縮比和性能都比較好的方式。7z具有最大的壓縮比,但壓縮時長超過百毫秒,在實時的業務系統中是不可接受的。

對于解壓來說,無論采用何種壓縮方式,何種壓縮級別,解壓需要的時間都是非常少的。

看完上述內容,你們掌握Java性能優化中如何進行壓縮的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

福清市| 句容市| 旬邑县| 乐平市| 龙泉市| 图们市| 苏尼特左旗| 安吉县| 喜德县| 克东县| 修武县| 集安市| 涟源市| 科技| 株洲县| 肃南| 镇原县| 临澧县| 波密县| 枣强县| 绍兴市| 灌南县| 颍上县| 扬州市| 林西县| 馆陶县| 定南县| 济阳县| 农安县| 寿阳县| 镇安县| 灵川县| 通河县| 盐池县| 株洲县| 迭部县| 长顺县| 涪陵区| 赞皇县| 邯郸县| 兴国县|