posts - 9, comments - 4, trackbacks - 0, articles - 21
          author: ZJ 2007-11-6
           
          一個Java類中可以存在多種形式的變量,可以是最一般的成員變量;或將其定義為靜態變量;也可以在方法中定義臨時變量。這三種變量的存取效率如何?
          1.測試
          下面作個實驗,看下面代碼。
          class CheckVars {
              privateintinstVar;// 成員變量
              privatestaticintstaticVar; // 靜態變量
           
              // 存取類方法中的臨時變量
              void tempAccess(int val) {
                 int j = 0;// 臨時變量
                 long startTime = System.currentTimeMillis();
                 for (int i = 0; i < val; i++)
                     j += 1;
                 long endTime = System.currentTimeMillis();
                 System.out.println("temp var: " + (endTime - startTime) + " milli seconds");
              }
           
              // 存取類的成員變量
              void instanceAccess(int val) {
                 long startTime = System.currentTimeMillis();
                 for (int i = 0; i < val; i++)
                     instVar += 1;
                 long endTime = System.currentTimeMillis();
                 System.out.println("instance var: " + (endTime - startTime) + " milli seconds");
              }
           
              // 存取類的 static 變量
              void staticAccess(int val) {
                 long startTime = System.currentTimeMillis();
                 for (int i = 0; i < val; i++)
                     staticVar += 1;
                 long endTime = System.currentTimeMillis();
                 System.out.println("static var: " + (endTime - startTime) + " milli seconds");
              }
             
              publicstaticvoid main(String[] args){
                 CheckVars test=new CheckVars();
                 test.tempAccess(200000000);
                 test.instanceAccess(200000000);
                 test.staticAccess(200000000);
              }
          }
           
          結果:
          temp var: 350 milli seconds
          instance var: 821 milli seconds
          static var: 852 milli seconds
           
          這段代碼中的每個方法都執行相同的循環并反復相同的次數。唯一的不同是每個循環使一個不同類型的變量遞增。方法 tempAccess 使一個局部堆棧變量遞增,instanceAccess 使類的一個成員實例變量遞增,而 staticAccess 使類的一個 static 變量遞增。
          從結果中可以發現,instanceAccess staticAccess 的執行時間基本相同。但是,tempAccess 要快兩到三倍。
           
          2JVM存取變量機制
          存取堆棧變量如此快是因為JVM 存取堆棧變量比它存取 static 變量或類的實例變量執行的操作少。
          JVM 是一種基于堆棧的虛擬機,因此優化了對堆棧數據的存取和處理。所有局部變量都存儲在一個局部變量表中,在 Java 操作數堆棧中進行處理,并可被高效地存取。
          存取 static 變量和實例變量成本更高,因為 JVM 必須使用代價更高的操作碼,并從常數存儲池中存取它們。(常數存儲池保存一個類型所使用的所有類型、字段和方法的符號引用。)通常,在第一次從常數存儲池中訪問 static 變量或實例變量以后,JVM 將動態更改字節碼以使用效率更高的操作碼。盡管有這種優化,堆棧變量的存取仍然更快。
           
          3.優化代碼
          考慮到這些事實,就可以重新構建前面的代碼,以便通過存取堆棧變量而不是實例變量或 static 變量使操作更高效。
          publicclass CheckVarsAdv {
              privateintinstVar;
              privatestaticintstaticVar;
           
              void tempAccess(int val) {
                 int j = 0;
                 long startTime = System.currentTimeMillis();
                 for (int i = 0; i < val; i++)
                     j += 1;
                 long endTime = System.currentTimeMillis();
                 System.out.println("temp var: " + (endTime - startTime) + " milli seconds");
              }
           
              void instanceAccess(int val) {
                 int j = instVar;
                 long startTime = System.currentTimeMillis();
                 for (int i = 0; i < val; i++)
                     j += 1;
                 long endTime = System.currentTimeMillis();
                 System.out.println("instance var: " + (endTime - startTime) + " milli seconds");
                 instVar = j;
              }
           
              void staticAccess(int val) {
                 int j = staticVar;
                 long startTime = System.currentTimeMillis();
                 for (int i = 0; i < val; i++)
                     j += 1;
                 long endTime = System.currentTimeMillis();
                 System.out.println("static var: " + (endTime - startTime) + " milli seconds");
                 staticVar = j;
              }
             
              publicstaticvoid main(String[] args){
                 CheckVarsAdv test=new CheckVarsAdv();
                 test.tempAccess(200000000);
                 test.instanceAccess(200000000);
                 test.staticAccess(200000000);
              }
          }
           
          結果:
          temp var: 341 milli seconds
          instance var: 370 milli seconds
          static var: 361 milli seconds
           
          方法 instanceAccess staticAccess 被修改為將它們的實例變量或 static 變量復制到局部堆棧變量中。當變量的處理完成以后,其值又被復制回實例變量或 static 變量中。這種簡單的更改明顯提高了 instanceAccess staticAccess 的性能。這三個方法的執行時間現在基本相同。

          本文出自 “子 孑” 博客,請務必保留此出處http://zhangjunhd.blog.51cto.com/113473/49322

          主站蜘蛛池模板: 梁平县| 台安县| 凌云县| 西平县| 安福县| 霍城县| 临朐县| 张家界市| 滦平县| 冀州市| 洪湖市| 峨眉山市| 永平县| 桑日县| 西城区| 绥滨县| 永修县| 常州市| 福鼎市| 章丘市| 马鞍山市| 临海市| 陇西县| 盐边县| 长乐市| 故城县| 冷水江市| 双鸭山市| 易门县| 磐石市| 昔阳县| 石狮市| 乐山市| 革吉县| 虞城县| 盐亭县| 华坪县| 海晏县| 涟水县| 合肥市| 徐汇区|