什么是java字节码性能getfield vs invokevirtual

时间:2017-03-24 17:30:28

标签: java performance bytecode

哪种表现更好?

我没有经过测试就问了这个问题因为我很懒。现在经过测试,它显示 getMethod略快于.field

Integer xj = x.getJ();` 

Integer yj = x.j;

这是我编译后的java字节代码

 L5 {
     aload1
     invokevirtual testj/ByteCodeTest getJ(()Ljava/lang/Integer;);
     astore4
 }
 L6 {
     aload1
     getfield testj/ByteCodeTest.j:java.lang.Integer
     astore5
 }

以下是我正在测试的代码:

    public void setPoint(){
    point=System.currentTimeMillis();
    System.out.println("point"+point);
}
public void comparePoint(){
    long endPoint=System.currentTimeMillis();
    System.out.println("endPoint"+endPoint);
    System.out.println("inteval"+(endPoint-point));
}
int count =2000000000;
public void test22(){
    ByteCodeTest x = new ByteCodeTest();
    setPoint();
    for(int i=0;i<count;i++){
        int yy= x.i+1;
    }
    comparePoint();
    setPoint();
    for(int i=0;i<count;i++){
        int yy=x.getI()+1;
    }
    comparePoint();
}

以下是代码输出:

point1490454906205

endPoint1490454907447

inteval1242

point1490454907448

endPoint1490454908666

inteval1218

这意味着getMethod比.field

略快

3 个答案:

答案 0 :(得分:5)

字段访问比方法调用更快,但除非您在紧密循环中编写极其性能敏感的代码,否则使用一个而不是另一个的决定是设计,而不是性能。

将JIT添加到混音中,您可能无法通过直接字段访问获得任何优势。

答案 1 :(得分:3)

字节码不同,但最后,JIT将通过内联getter来优化访问。与编写代码的程序员不同,JIT可以随时准确地判断是否覆盖了getter。相信JIT,从长远来看,性能是相同的。

可维护性不一样。使用getter方法允许您使用扩展/修改逻辑覆盖getter(这样做的代价是使getter多态,导致性能损失很小,另一方面,直接字段访问甚至不可能)。

使用直接字段访问不会带来任何好处,但是当代码稍后发展时会有很多陷阱。

答案 2 :(得分:0)

使用getter时,调用的函数会降低性能,而不仅仅是访问字段。如果你在第一种情况下查看你的字节代码,你应该找到getJ的定义,在这里调用。