美文网首页
为什么有些Java 类方法中要cache类变量

为什么有些Java 类方法中要cache类变量

作者: yangweigbh | 来源:发表于2018-01-18 20:00 被阅读154次

    比如以下一段java代码:

    private void performTraversals() {
        // cache mView since it is used so much below...
        final View host = mView;
    
        ......
    }
    

    为什么要这么写呢?

    下面用一段测试程序的bytecode来解释一下(以下bytecode是基于JVM的,不是基于art的):

    public class TestLocal {
        private int i = 1;
    
        public void foo() {
            long before = System.currentTimeMillis();
            for (int j = 0; j < 10000; j++) {
                System.out.print(i);
            }
    
            System.out.println();
            System.out.println("TestLocal result: " + (System.currentTimeMillis() - before));
        }
    
        public static void main(String[] args) {
            new TestLocal().foo();
            new TestLocal2().foo();
        }
    }
    
    
    class TestLocal2 {
        private int i = 1;
    
        public void foo() {
            int k = i;
            long before = System.currentTimeMillis();
            for (int j = 0; j < 10000; j++) {
                System.out.print(k);
            }
    
            System.out.println();
            System.out.println("TestLocal2 result: " + (System.currentTimeMillis() - before));
        }
    }
    

    TestLocalfoo方法,直接读取类变量,对应的字节码是

            13: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
            16: aload_0
            17: getfield      #2                  // Field i:I
            20: invokevirtual #5                  // Method java/io/PrintStream.print:(I)V
    

    每次都需要将this push到operand stack中,然后去堆里找对应的field。

    TestLocal2foo方法,是将类变量的值存储在当前Frame的local variable中。然后每次调用只要从local variable中取用。

             0: aload_0
             1: getfield      #2                  // Field i:I
             4: istore_1
             .......
            20: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
            23: iload_1
            24: invokevirtual #5                  // Method java/io/PrintStream.print:(I)V
    

    运行时间对比:

    TestLocal result: 145 ms
    TestLocal2 result: 128 ms
    

    所以将类变量缓存到方法的local variable中还是能提升运行速度的,尤其是如果类变量会被经常访问。

    相关文章

      网友评论

          本文标题:为什么有些Java 类方法中要cache类变量

          本文链接:https://www.haomeiwen.com/subject/lpbwoxtx.html