<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    瘋狂

    STANDING ON THE SHOULDERS OF GIANTS
    posts - 481, comments - 486, trackbacks - 0, articles - 1
      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    盡可能使用堆棧變量

    Posted on 2010-01-29 14:56 瘋狂 閱讀(437) 評(píng)論(0)  編輯  收藏 所屬分類: java 、java性能

    如果您頻繁存取變量,就需要考慮從何處存取這些變量。變量是
    static

    變量,還是堆棧變量,或者是類的實(shí)例變量?變量的存儲(chǔ)位置對(duì)存取它的代碼的性能有明顯的影響?例如,請(qǐng)考慮下面這段代碼:

    class StackVars
                {
                private int instVar;
                private static int staticVar;
                //存取堆棧變量
                void stackAccess(int val)
                {
                int j=0;
                for (int i=0; i<val; i++)
                j += 1;
                }
                //存取類的實(shí)例變量
                void instanceAccess(int val)
                {
                for (int i=0; i<val; i++)
                instVar += 1;
                }
                //存取類的 static 變量
                void staticAccess(int val)
                {
                for (int i=0; i<val; i++)
                staticVar += 1;
                }
                }
                

    這段代碼中的每個(gè)方法都執(zhí)行相同的循環(huán),并反復(fù)相同的次數(shù)。唯一的不同是每個(gè)循環(huán)使一個(gè)不同類型的變量遞增。方法
    stackAccess

    使一個(gè)局部堆棧變量遞增, instanceAccess 使類的一個(gè)實(shí)例變量遞增,而 staticAccess 使類的一個(gè) static 變量遞增。

    instanceAccessstaticAccess 的執(zhí)行時(shí)間基本相同。但是, stackAccess 要快兩到三倍。存取堆棧變量如此快是因?yàn)?,JVM 存取堆棧變量比它存取 static 變量或類的實(shí)例變量執(zhí)行的操作少。請(qǐng)看一下為這三個(gè)方法生成的字節(jié)碼:

    Method void stackAccess(int)
                0 iconst_0         //將 0 壓入堆棧。
                1 istore_2         //彈出 0 并將它存儲(chǔ)在局部分變量表中索引為 2 的位置 (j)。
                2 iconst_0         //壓入 0。
                3 istore_3         //彈出 0 并將它存儲(chǔ)在局部變量表中索引為 3 的位置 (i)。
                4 goto 13          //跳至位置 13。
                7 iinc 2 1         //將存儲(chǔ)在索引 2 處的 j 加 1。
                10 iinc 3 1         //將存儲(chǔ)在索引 3 處的 i 加 1。
                13 iload_3          //壓入索引 3 處的值 (i)。
                14 iload_1          //壓入索引 1 處的值 (val)。
                15 if_icmplt 7      //彈出 i 和 val。如果 i 小于 val,則跳至位置 7。
                18 return           //返回調(diào)用方法。
                Method void instanceAccess(int)
                0 iconst_0         //將 0 壓入堆棧。
                1 istore_2         //彈出 0 并將它存儲(chǔ)在局部變量表中索引為 2 的位置 (i)。
                2 goto 18          //跳至位置 18。
                5 aload_0          //壓入索引 0 (this)。
                6 dup              //復(fù)制堆棧頂?shù)闹挡⑺鼔喝搿?
                7 getfield #19 <Field int instVar>
                //彈出 this 對(duì)象引用并壓入 instVar 的值。
                10 iconst_1         //壓入 1。
                11 iadd             //彈出棧頂?shù)膬蓚€(gè)值,并壓入它們的和。
                12 putfield #19 <Field int instVar>
                //彈出棧頂?shù)膬蓚€(gè)值并將和存儲(chǔ)在 instVar 中。
                15 iinc 2 1         //將存儲(chǔ)在索引 2 處的 i 加 1。
                18 iload_2          //壓入索引 2 處的值 (i)。
                19 iload_1          //壓入索引 1 處的值 (val)。
                20 if_icmplt 5      //彈出 i 和 val。如果 i 小于 val,則跳至位置 5。
                23 return           //返回調(diào)用方法。
                Method void staticAccess(int)
                0 iconst_0         //將 0 壓入堆棧。
                1 istore_2         //彈出 0 并將它存儲(chǔ)在局部變量表中索引為 2 的位置 (i)。
                2 goto 16          //跳至位置 16。
                5 getstatic #25 <Field int staticVar>
                //將常數(shù)存儲(chǔ)池中 staticVar 的值壓入堆棧。
                8 iconst_1         //壓入 1。
                9 iadd             //彈出棧頂?shù)膬蓚€(gè)值,并壓入它們的和。
                10 putstatic #25 <Field int staticVar>
                //彈出和的值并將它存儲(chǔ)在 staticVar 中。
                13 iinc 2 1         //將存儲(chǔ)在索引 2 處的 i 加 1。
                16 iload_2          //壓入索引 2 處的值 (i)。
                17 iload_1          //壓入索引 1 處的值 (val)。
                18 if_icmplt 5      //彈出 i 和 val。如果 i 小于 val,則跳至位置 5。
                21 return           //返回調(diào)用方法。
                

    查看字節(jié)碼揭示了堆棧變量效率更高的原因。JVM 是一種基于堆棧的虛擬機(jī),因此優(yōu)化了對(duì)堆棧數(shù)據(jù)的存取和處理。所有局部變量都存儲(chǔ)在一個(gè)局部變量表中,在 Java 操作數(shù)堆棧中進(jìn)行處理,并可被高效地存取。存取 static 變量和實(shí)例變量成本更高,因?yàn)?JVM 必須使用代價(jià)更高的操作碼,并從常數(shù)存儲(chǔ)池中存取它們。(常數(shù)存儲(chǔ)池保存一個(gè)類型所使用的所有類型、字段和方法的符號(hào)引用。)

    通常,在第一次從常數(shù)存儲(chǔ)池中訪問(wèn) static 變量或?qū)嵗兞恳院螅琂VM 將動(dòng)態(tài)更改字節(jié)碼以使用效率更高的操作碼。盡管有這種優(yōu)化,堆棧變量的存取仍然更快。

    考慮到這些事實(shí),就可以重新構(gòu)建前面的代碼,以便通過(guò)存取堆棧變量而不是實(shí)例變量或 static 變量使操作更高效。請(qǐng)考慮修改后的代碼:

    class StackVars
                {
                //與前面相同...
                void instanceAccess(int val)
                {
                int j = instVar;
                for (int i=0; i<val; i++)
                j += 1;
                instVar = j;
                }
                void staticAccess(int val)
                {
                int j = staticVar;
                for (int i=0; i<val; i++)
                j += 1;
                staticVar = j;
                }
                }
                

    方法 instanceAccessstaticAccess 被修改為將它們的實(shí)例變量或 static 變量復(fù)制到局部堆棧變量中。當(dāng)變量的處理完成以后,其值又被復(fù)制回實(shí)例變量或 static 變量中。這種簡(jiǎn)單的更改明顯提高了 instanceAccessstaticAccess 的性能。這三個(gè)方法的執(zhí)行時(shí)間現(xiàn)在基本相同, instanceAccessstaticAccess 的執(zhí)行速度只比 stackAccess 的執(zhí)行速度慢大約 4%。

    這并不表示您應(yīng)該避免使用 static 變量或?qū)嵗兞俊D鷳?yīng)該使用對(duì)您的設(shè)計(jì)有意義的存儲(chǔ)機(jī)制。例如,如果您在一個(gè)循環(huán)中存取 static 變量或?qū)嵗兞?,則您可以臨時(shí)將它們存儲(chǔ)在一個(gè)局部堆棧變量中,這樣就可以明顯地提高代碼的性能。這將提供最高效的字節(jié)碼指令序列供 JVM 執(zhí)行
    轉(zhuǎn)載自ibm

    主站蜘蛛池模板: 日韩亚洲国产高清免费视频| 一本色道久久88亚洲综合| 亚洲无吗在线视频| 在线观看免费国产视频| 免费无码一区二区三区蜜桃| 视频一区在线免费观看| 亚洲综合最新无码专区| 久艹视频在线免费观看| 亚洲日本乱码一区二区在线二产线| 91成人免费观看在线观看| 91亚洲va在线天线va天堂va国产| 日本人成在线视频免费播放| 亚洲制服在线观看| 免费精品国产自产拍在| 亚洲乱码一二三四区麻豆| 亚洲成A人片77777国产| 91福利视频免费观看| 久久精品国产亚洲av天美18| 国产成人无码a区在线观看视频免费| 亚洲AV无码国产精品永久一区| 成**人免费一级毛片| 中文字幕无码毛片免费看| 亚洲色无码专区一区| 亚洲AV综合色区无码一区| 在线观看免费无码视频| 亚洲日韩精品国产3区| 亚洲韩国精品无码一区二区三区| 午夜网站在线观看免费完整高清观看| 亚洲av日韩av不卡在线观看| 午夜私人影院免费体验区| 久久国产精品国产自线拍免费| 亚洲男人都懂得羞羞网站| 又黄又爽一线毛片免费观看| 日韩免费在线观看视频| 白白色免费在线视频| 亚洲一区二区三区香蕉| 67194国产精品免费观看| 亚洲不卡影院午夜在线观看| 国产精品久久久亚洲| 国产一区二区三区在线免费观看| 四虎国产精品成人免费久久|