性能:我应该避免构造函数委派吗?

oct*_*pod 15 java performance constructor

我想知道在构造函数(也就是构造函数委托)中运行构造函数之间是否存在任何性能差异.

请不要将此问题解释为支持冗余,例如复制长构造函数以提高性能.据我所知,在大多数情况下,除了性能之外,还需要在构造函数中调用构造函数.(例如,可读性)

例如,这是Vector3D我最近创建的一个类:

public class Vector3D {

    public final int x, y, z;

    public Vector3D() {
        this(0, 0, 0);
    }

    public Vector3D(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}
Run Code Online (Sandbox Code Playgroud)

我是否会因为不打电话this(0, 0, 0)而单独设置变量而受益?

public class Vector3D {

    public final int x, y, z;

    public Vector3D() {
        this.x = 0;
        this.y = 0;
        this.z = 0;
    }

    public Vector3D(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}
Run Code Online (Sandbox Code Playgroud)

Dic*_*ici 10

您永远不会受益于重复代码.这是不成熟的优化.方法调用不需要任何费用,除非您在短时间内经常执行它.在这种情况下,如果代码未在系统的太多位置使用,则可以内联代码,但这不是您的情况.

想象一下,有一天你会在课堂上添加另一个功能.如果您内联代码,则必须更新两个构造函数而不是单个构造函数.逻辑相关的所有代码位应该在代码中相关(基本上调用相同的nethods /使用相同的类).这就是你构建可重用代码的方法.

不要过分思考性能,首先要考虑设计,清晰度和可重用性.系统中真正需要高性能的部分是算法部分,这不应该影响设计.

  • 因为代码是针对人类的,并且必须是可读的.你不知道你的代码在编译时会发生什么,但我的猜测是它会编译成单独的构造函数但是你编写它.有一种语法可以调用同一个类的其他构造函数,信任语言创建者并使用它,他们必须考虑它. (3认同)

Kra*_*rab 6

Main.java

package pokus1;

public class Main {

    public int m_a;
    public int m_b;

    public Main(int a, int b) {

        m_a = a;
        m_b = b;

    }

    public Main() {
        this(0,0);
    }

    public static void main(String[] args) {

        Main main = new Main();

    }

}
Run Code Online (Sandbox Code Playgroud)

pokus1.Main()的Javap输出(javap -v Main.class):

你看到invokespecial偏移的说明3吗?这是对此的呼吁pokus1.Main(int a,int b).所以基本上是的,不调用第二个构造函数更有效.但是在当前的JVM实现中有很多优化,比如方法内联,即时编译等,所以我认为你不需要考虑它,否则你可以考虑每个java调用,如果有必要的话.

public pokus1.Main();
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=1, args_size=1
         0: aload_0       
         1: iconst_0      
         2: iconst_0      
         3: invokespecial #24                 // Method "<init>":(II)V
         6: return        
      LineNumberTable:
        line 16: 0
        line 17: 6
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       7     0  this   Lpokus1/Main;
Run Code Online (Sandbox Code Playgroud)

  • @Dici:因为JVM非常好.如果你的程序运行时间很短,那么如果你内联很少的指令并不重要.如果您的程序将运行很长时间,JVM将负责处理它. (2认同)

mer*_*ike 5

通常,根本没有区别,因为及时编译器内联了短方法

而且,即使代码没有内联,机器代码中两条分支指令造成的开销也不大可能对整个程序的运行时间产生实质性影响,除非程序大部分时间都花在这些向量上。