日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
優(yōu)化Java中的多態(tài)代碼走進(jìn)新版OpenJDK

優(yōu)化Java中的多態(tài)代碼

創(chuàng)新互聯(lián)公司專注于企業(yè)成都全網(wǎng)營銷推廣、網(wǎng)站重做改版、江州網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5頁面制作、商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為江州等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

Oracle的Java是一個(gè)門快速的語言,有時(shí)候它可以和C++一樣快。編寫Java代碼時(shí),我們通常使用接口、繼承或者包裝類(wrapper class)來實(shí)現(xiàn)多態(tài),使軟件更加靈活。不幸的是,多態(tài)會引入更多的調(diào)用,讓Java的性能變得糟糕。部分問題是,Java不建議使用完全的內(nèi)聯(lián)代碼,即使它是非常安全的。(這個(gè)問題可能會在***的Java版本里得到緩解,請看文章后面的更新部分)

考慮下這種情況,我們要用接口抽象出一個(gè)整型數(shù)組:

 
 
  1. public interface Array { 
  2.     public int get(int i); 
  3.     public void set(int i, int x); 
  4.     public int size(); 

你為什么要這樣做?可能是因?yàn)槟愕臄?shù)據(jù)是保存在數(shù)據(jù)庫里、網(wǎng)絡(luò)上、磁盤上或者在其他的數(shù)據(jù)結(jié)構(gòu)里。你想一次編碼后就不用關(guān)心數(shù)組的具體實(shí)現(xiàn)。

編寫一個(gè)與標(biāo)準(zhǔn)Java數(shù)組一樣高效率的類并不難,不同之處在于它實(shí)現(xiàn)了這個(gè)接口:

 
 
  1. public final class NaiveArray implements Array { 
  2.     protected int[] array; 
  3.   
  4.     public NaiveArray(int cap) { 
  5.         array = new int[cap]; 
  6.     } 
  7.   
  8.     public int get(int i) { 
  9.         return array[i]; 
  10.     } 
  11.   
  12.     public void set(int i, int x) { 
  13.         array[i] = x;  
  14.     } 
  15.   
  16.     public int size() { 
  17.         return array.length; 
  18.     } 

至少在理論上,NaiveArray類不會出現(xiàn)任何的性能問題。這個(gè)類是final的,所有的方法都很簡短。

不幸的是,在一個(gè)簡單的benchmark類里,當(dāng)使用NavieArray作為數(shù)組實(shí)例時(shí),你會發(fā)現(xiàn)NavieArray比標(biāo)準(zhǔn)數(shù)組慢5倍以上。就像這個(gè)例子:

 
 
  1. public int compute() { 
  2.    for(int k = 0; k < array.size(); ++k) 
  3.       array.set(k,k); 
  4.    int sum = 0; 
  5.    for(int k = 0; k < array.size(); ++k) 
  6.       sum += array.get(k); 
  7.    return sum; 

你可以通過使用NavieArray作為NavieArray的一個(gè)實(shí)例來稍微減緩性能問題(避免使用多態(tài))。不幸的是,它依然會慢3倍多。而你僅是放棄了多態(tài)的好處。

那么,強(qiáng)制使用內(nèi)聯(lián)函數(shù)調(diào)用會怎樣?

一個(gè)可行的解決方法是手動(dòng)實(shí)現(xiàn)內(nèi)聯(lián)函數(shù)。你可以使用 instanceof 關(guān)鍵字來提供優(yōu)化實(shí)現(xiàn),否則你只會得到一個(gè)普通(更慢)的實(shí)現(xiàn)。例如,如果你使用下面的代碼,NavieArray就會變得和標(biāo)準(zhǔn)數(shù)組一樣快:

 
 
  1. public int compute() { 
  2.      if(array instanceof NaiveArray) { 
  3.         int[] back = ((NaiveArray) array).array; 
  4.         for(int k = 0; k < back.length; ++k) 
  5.            back[k] = k; 
  6.         int sum = 0; 
  7.         for(int k = 0; k < back.length; ++k) 
  8.            sum += back[k]; 
  9.         return sum; 
  10.      } 
  11.      //... 

當(dāng)然,我也會介紹一個(gè)維護(hù)問題作為需要實(shí)現(xiàn)不止一次的同類算法…… 當(dāng)出現(xiàn)性能問題時(shí),這是一個(gè)可接受的替代。

和往常一樣,我的benchmarking代碼可以在網(wǎng)上獲取到。

總結(jié)

  • 一些Java版本可能不完全支持頻繁的內(nèi)聯(lián)函數(shù)調(diào)用,即使它可以并且應(yīng)該支持。這會造成嚴(yán)重的性能問題。
  • 把類聲明為 final 看起來不會緩解性能問題。
  • 對于消耗大的函數(shù),可行的解決方法是自己手動(dòng)優(yōu)化多態(tài)和實(shí)現(xiàn)內(nèi)聯(lián)函數(shù)調(diào)用。使用 instanceof 關(guān)鍵字,你可以為一些特定的類編寫代碼并且(因此)保留多態(tài)的靈活性。

更新

Erich Schubert使用 double 數(shù)組運(yùn)行簡單的benchmark類發(fā)現(xiàn)他的運(yùn)行結(jié)果與我的結(jié)果相矛盾,而且我們的變量實(shí)現(xiàn)都是一樣的。我通過更新到***版本的OpenJDK證明了他的結(jié)果。下面的表格給出了處理10百萬整數(shù)需要的納秒時(shí)間:

 Function  Oracle JDK 8u11  OpenJDK 1.8.0_40  OpenJDK 1.7.0_65
straight arrays0.920.710.87
with interface5.90.706.3
with manual inlining0.980.710.93

正如我們看到的,***版本的OpenJDK十分智能,并且消除了多態(tài)的性能開銷(1.8.0_40)。如果你足夠幸運(yùn)地在使用這個(gè)JDK,你不需要擔(dān)心這 篇文章所說的性能問題。但是,這個(gè)總體思想依然值得應(yīng)用在更復(fù)雜的場景里。例如,JDK優(yōu)化可能依然達(dá)不到你期待的性能要求。

原文鏈接: lemire 翻譯: ImportNew.com - 進(jìn)林

譯文鏈接: http://www.importnew.com/14393.html


網(wǎng)頁標(biāo)題:優(yōu)化Java中的多態(tài)代碼走進(jìn)新版OpenJDK
文章轉(zhuǎn)載:http://www.5511xx.com/article/cohcdii.html