国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

專家釋疑:輕松提高Java代碼的性能

2019-11-17 05:58:47
字體:
來源:轉載
供稿:網友

  尾遞歸轉換能加快應用程序的速度,但不是所有的 JVM 都會做這種轉換,很多算法用尾遞歸方法表示會顯得格外簡明。編譯器會自動把這種方法轉換成循環,以提高程序的性能。但在 java 語言規范中,并沒有要求一定要作這種轉換,因此,并不是所有的 Java 虛擬機(JVM)都會做這種轉換。這就意味著在 Java 語言中采用尾遞歸表示可能導致巨大的內存占用,而這并不是我們期望的結果。Eric Allen 在本文中闡述了動態編譯將會保持語言的語義,而靜態編譯則通常不會。他說明了為什么這是一個重要問題,并提供了一段代碼來幫助判定您的即時(JIT)編譯器是否會在保持語言語義的同時做尾遞歸代碼轉換。

  尾遞歸及其轉換

  相當多的程序包含有循環,這些循環運行的時間占了程序總運行時間的很大一部分。這些循環經常要反復更新不止一個變量,而每個變量的更新又經常依靠于其它變量的值。

  假如把迭代看成是尾遞歸函數,那么,就可以把這些變量看成是函數的參數。簡單提醒一下:假如一個調用的返回值被作為調用函數的值立即返回,那么,這個遞歸調用就是尾遞歸;尾遞歸不必記住調用時調用函數的上下文。 

  由于這一特點,在尾遞歸函數和循環之間有一個很好的對應關系:可以簡單地把每個遞歸調用看作是一個循環的多次迭代。但因為所有可變的參數值都一次傳給了遞歸調用,所以比起循環來,在尾遞歸中可以更輕易地得到更新值。而且,難以使用的 break 語句也經常為函數的簡單返回所替代。  

  但在 Java 編程中,用這種方式表示迭代將導致效率低下,因為大量的遞歸調用有導致堆棧溢出的危險。  

  解決方案比較簡單:因為尾遞歸函數實際上只是編寫循環的一種更簡單的方式,所以就讓編譯器把它們自動轉換成循環形式。這樣您就同時利用了這兩種形式的優點。  

  但是,盡管大家都熟知如何把一個尾遞歸函數自動轉換成一個簡單循環,Java 規范卻不要求做這種轉換。不作這種要求的原因大概是:通常在面向對象的語言中,這種轉換不能靜態地進行。相反地,這種從尾遞歸函數到簡單循環的轉換必須由 JIT 編譯器動態地進行。  

  要理解為什么會是這樣,考慮下面一個失敗的嘗試:在 Integers 集上,把 Iterator 中的元素相乘。  

  因為下面的程序中有一個錯誤,所以在運行時會拋出一個異常。但是,就象在本專欄以前的許多文章中已經論證的那樣,一個程序拋出的精確異常(跟很棒的錯誤類型標識符一樣)對于找到錯誤藏在程序的什么地方并沒有什么幫助,我們也不想編譯器以這種方式改變程序,以使編譯的結果代碼拋出一個不同的異常。  

  清單 1. 一個把 Integer 集的 Iterator 中的元素相乘的失敗嘗試 

import java.util.Iterator; 

public class Example { 

  public int PRodUCt(Iterator i) { 
    return productHelp(i, 0); 
  } 

  int productHelp(Iterator i, int accumulator) { 
    if (i.hasNext()) { 
      return productHelp(i, accumulator * ((Integer)i.next()).intValue()); 
    } 
    else { 
      return accumulator; 
    } 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 突泉县| 名山县| 华容县| 舞钢市| 海门市| 兴山县| 临澧县| 清镇市| 三原县| 浠水县| 阿克陶县| 紫金县| 延寿县| 凤凰县| 永昌县| 临沭县| 寿光市| 郓城县| 鄂托克旗| 罗甸县| 尚志市| 修文县| 阳原县| 濮阳县| 英吉沙县| 霍山县| 新乐市| 嵊泗县| 砚山县| 正定县| 石景山区| 阿鲁科尔沁旗| 花莲市| 元江| 曲阜市| 从江县| 溆浦县| 郁南县| 阿坝县| 石屏县| 阿克陶县|