六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

提高 Java 代碼性能

[摘要]尾遞歸轉換能加快應用程序的速度,但不是所有的 JVM 都會做這種轉換   很多算法用尾遞歸方法表示會顯得格外簡明。編譯器會自動把這種方法轉換成循環,以提高程序的性能。但在 Java 語言規范中,并沒有要求一定要作這種轉換,因此,并不是所有的 Java 虛擬機(JVM)都會做這種轉換。這就意味著在 ...
尾遞歸轉換能加快應用程序的速度,但不是所有的 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;
   }
   }
  }
  注意 product 方法中的錯誤。product 方法通過把 accumulator 賦值為 0 調用 productHelp。它的值應為 1。否則,在類 Example 的任何實例上調用 product 都將產生 0 值,不管 Iterator 是什么值。

  假設這個錯誤終于被改正了,但同時,類 Example 的一個子類也被創建了,如清單 2 所示:

  清單 2. 試圖捕捉象清單 1 這樣的不正確的調用

  import java.util.*;

  class Example {

   public int product(Iterator i) {
   return productHelp(i, 1);
   }

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

  // And, in a separate file:

  import java.util.*;

  public class Example2 extends Example {
   int productHelp(Iterator i, int accumulator) {
   if (accumulator < 1)="" {="">
   throw new RuntimeException("accumulator to productHelp must be >= 1");
   }
   else {
   return super.productHelp(i, accumulator);
   }
   }

   public static void main(String[] args) {
   LinkedList l = new LinkedList();
   l.add(new Integer(0));
   new Example2().product(l.listIterator());
   }
  }
  類 Example2 中的被覆蓋的 productHelp 方法試圖通過當 accumulator 小于“1”時拋出運行時異常來捕捉對 productHelp 的不正確調用。不幸的是,這樣做將引入一個新的錯誤。如果 Iterator 含有任何 0 值的實例,都將使 productHelp 在自身的遞歸調用上崩潰。



主站蜘蛛池模板: 亚洲精品免费在线 | 日韩一区二区三区免费视频 | 亚洲国产天堂久久综合图区 | 青青草视频在线观看免费 | 欧美亚洲国产激情一区二区 | 热久久影院 | 亚洲男人天堂影院 | 人人看97 | 色综合五月 | 欧美一区二区激情三区 | 天天综合色天天综合 | 青青青国产免费手机视频在线观看 | 青青青爽线在线视频观看 | 日本久久免费大片 | 欧美一级免费片 | 午夜免费影视 | 一区二区三区视频网站 | 欧美怡红院高清在线 | 亚洲综合中文 | 日本一区不卡在线观看 | 日本人成免费大片 | 亚洲产国偷v产偷v自拍色戒 | 日本亚洲欧美国产日韩ay高清 | 一级毛片免费毛片一级毛片免费 | 日本成a人片在线观看网址 日本草草影院 | 青青草原亚洲 | 天天弄天天模 | 天天色天天干天天射 | 在线免费观看日本 | 天天骑夜夜操 | 色综合图区 | 日日人人| 日本一道本中文字幕 | 青娱极品盛宴国产一区 | 婷婷影院在线综合免费视频 | 日韩美视频网站 | 天天做日日爱 | 一二三四免费观看高清观看在线 | 天天爱天天做久久天天狠狼 | 亚洲精品午夜久久aaa级久久久 | 亚洲图片在线欧美专区图片 |