【編者按】本文作者為 Ali Kemal TASCI践图,最早于2016年4月9日發(fā)布于DZONE社區(qū)。文章主要介紹通過改進(jìn) Java 1.5 就已存在的骨灰級(jí)特性大幅度提高應(yīng)用性能沉馆。
本文系 OneAPM 工程師編譯呈現(xiàn)码党,以下為正文。
如果我告訴你:“只要修改一個(gè)字符斥黑,下面這段代碼的運(yùn)行速度就能提高5倍揖盘。”锌奴,你覺得可能么兽狭?
long t = System.currentTimeMillis();
Long sum = 0L;for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println("total:" + sum);
System.out.println("processing time: " + (System.currentTimeMillis() - t) + " ms");
輸出結(jié)果:
總數(shù):2305843005992468481
處理時(shí)間:6756 ms
仔細(xì)琢磨一下,你可能會(huì)想到下面這種執(zhí)行速度更快的實(shí)現(xiàn)方法:
long t = System.currentTimeMillis();//Long sum = 0L;long sum = 0L;for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println("total:" + sum);
System.out.println("processing time: " + (System.currentTimeMillis() - t) + " ms") ;
輸出結(jié)果:
總數(shù):2305843005992468481
處理時(shí)間:1248 ms
其實(shí)缨叫,自動(dòng)裝箱(Autoboxing)的草率使用是造成速度差異的根本原因椭符,而這一特性從 Java 1.5 開始就已出現(xiàn)了。
在繼續(xù)解釋造成差異的細(xì)節(jié)之前耻姥,讓我們仔細(xì)回味一下 Java 中的這兩個(gè)概念:自動(dòng)裝箱(Autoboxing)與 拆箱(Unboxing)销钝。
Java 中的變量分為兩種:原始型與引用型。一共存在8個(gè)原始型變量以及與各個(gè)原始變量對(duì)應(yīng)的8個(gè)引用變量(包裝類)琐簇。
Primitive Types(原始型) | Reference Types(Wrapper Class)(引用型蒸健,(包裝類)) |
---|---|
boolean | Boolean |
byte | Byte |
char | Character |
float | Float |
int | Integer |
long | Long |
short | Short |
double | Double |
下面的代碼會(huì)介紹”Autoboxing“與”Unboxing“的用例座享。在這段代碼中,一個(gè)類型為”long”的值被添加到類型為”Long“的List集合中似忧。在 Java 1.4 中渣叛,為了實(shí)現(xiàn)此操作,我們必須將原始變量賦值到合適的引用類中(也即裝箱盯捌,boxing)淳衙。從 Java 1.5 開始,編譯器會(huì)幫我們完成這一操作饺著。所以箫攀,我們不再需要寫那么多代碼。
List<Long> longList = new ArrayList<>();
long i = 4;
longList.add( i ); //autoboxing long j = longList.get( 0 ); //unboxing
從 Java 1.5 開始幼衰,編譯器會(huì)自動(dòng)將上面的代碼段轉(zhuǎn)化成如下代碼:
List<Long> longList = new ArrayList<>();
long i = 4;
longList.add(Long.valueOf( i ) );
long j = longList.get( 0 ).longValue();
因此靴跛,我們也可以說,前文出現(xiàn)的第一段代碼段會(huì)自動(dòng)轉(zhuǎn)化為如下代碼渡嚣。所以梢睛,導(dǎo)致處理時(shí)間較長(zhǎng)的原因也就水落石出了:不必要地創(chuàng)建了2147483647個(gè)”Long“類型實(shí)例。
long t = System.currentTimeMillis();
Long sum = 0L;for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += new Long(i);
}
System.out.println("total:" + sum);
System.out.println("processing time: " + (System.currentTimeMillis() - t) + " ms") ;
由此可知识椰,想要編寫速度更快的 Java 代碼绝葡,我們也需要考慮”Autoboxing”與”Unboxing”這樣的基礎(chǔ)概念。
相關(guān)資源集錦
Autoboxing and Unboxing
Autoboxing
Efective Java 2nd Edition, J. Bloch
OneAPM 為您提供端到端的 Java 應(yīng)用性能解決方案裤唠,我們支持所有常見的 Java 框架及應(yīng)用服務(wù)器挤牛,助您快速發(fā)現(xiàn)系統(tǒng)瓶頸,定位異常根本原因种蘸。分鐘級(jí)部署墓赴,即刻體驗(yàn),Java 監(jiān)控從來沒有如此簡(jiǎn)單航瞭。想閱讀更多技術(shù)文章诫硕,請(qǐng)?jiān)L問 OneAPM 官方技術(shù)博客。
本文轉(zhuǎn)自 OneAPM 官方博客
原文地址:https://dzone.com/articles/java-performance-notes-autoboxing-unboxing