什么是java字节码性能getfield与invokevirtual
哪个性能更好 我没有经过测试就问了这个问题,因为我很懒。现在经过测试,它显示getMethod比.field稍快一些 或 这是我反编译后的java字节码什么是java字节码性能getfield与invokevirtual,java,performance,bytecode,Java,Performance,Bytecode,哪个性能更好 我没有经过测试就问了这个问题,因为我很懒。现在经过测试,它显示getMethod比.field稍快一些 或 这是我反编译后的java字节码 L5 { aload1 invokevirtual testj/ByteCodeTest getJ(()Ljava/lang/Integer;); astore4 } L6 { aload1 getfield testj/ByteCodeTest.j:java.lang.Integer
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();
}
这意味着getMethod比.field稍快。当您使用getter时,您调用的函数会降低性能,而不仅仅是访问字段。如果您在第一种情况下查看字节码,您应该会找到getJ的定义,在这里调用。当您使用getter时,您调用的函数会降低性能,而不仅仅是访问字段。如果您在第一种情况下查看字节码,您应该会找到在这里调用的getJ的定义。字段访问比方法调用快,但是除非您在一个紧循环中编写对性能非常敏感的代码,否则使用一个而不是另一个的决定是设计,而不是性能 将JIT添加到混合中,您可能不会从直接字段访问中获得任何优势
您的测试表明,方法调用更快,但这是因为您是。性能是一个复杂的问题,初学者,甚至不是初学者,通常没有足够的经验来考虑一切。他们不知道如何衡量性能,他们担心在大多数软件中根本不会影响性能的无关微优化,他们不太了解JIT或其他正在发挥作用的东西,还有许多其他问题,使性能和缺乏经验的开发人员成为危险的混合体。字段访问比方法调用快,但除非您在一个紧密的循环中编写对性能非常敏感的代码,否则决定使用一个而不是另一个是设计,而不是性能 将JIT添加到混合中,您可能不会从直接字段访问中获得任何优势
您的测试表明,方法调用更快,但这是因为您是。性能是一个复杂的问题,初学者,甚至不是初学者,通常没有足够的经验来考虑一切。他们不知道如何衡量性能,他们担心在大多数软件中根本不会影响性能的无关微优化,他们不太了解JIT或其他正在发挥作用的东西,以及许多其他问题,这些问题使性能和缺乏经验的开发人员成为危险的组合。字节码不同,但最终,JIT将通过内联getter优化访问。与编写代码时的程序员不同,JIT可以在任何时候准确地判断getter是否被覆盖。相信JIT,从长远来看,性能是相同的 不一样的是可维护性。使用getter方法可以使用扩展/修改的逻辑覆盖getter。这样做的代价是使getter多态,从而导致较小的性能损失,另一方面,直接访问字段甚至不可能做到这一点
使用直接字段访问没有任何好处,但在以后的代码发展过程中会有很多陷阱。字节码是不同的,但最终,JIT将通过内联getter来优化访问。与编写代码时的程序员不同,JIT可以在任何时候准确地判断getter是否被覆盖。相信JIT,从长远来看,性能是相同的 不一样的是可维护性。使用getter方法可以使用扩展/修改的逻辑覆盖getter。这样做的代价是使getter多态,从而导致较小的性能损失,另一方面,直接访问字段甚至不可能做到这一点
使用直接字段访问没有任何好处,但在以后的代码开发过程中会有很多陷阱。为什么?出于性能原因,您是否打算选择一种而不是另一种?如果此时此刻的性能差异对您很重要,那么您可能应该使用较低级别的编程语言,而不是使用JavaWhy?出于性能原因,您是否打算选择其中一种?如果此时此刻的性能差异对您很重要,您可能应该使用较低级别的编程语言,而不是使用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