Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance: Should I avoid constructor delegation?

I was wondering if there is any performance difference between running a constructor from within a constructor (aka. constructor delegation) and not.

Please don't interpret this question as me supporting redundancy, like copying long constructors for a performance boost. I understand that in most cases, calling a constructor within a constructor is desirable for many reasons other than performance. (Readability, for example)

As an example, this is a Vector3D class that I've recently created:

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;
    }
}

Will I benefit from not calling this(0, 0, 0) and simply setting the variables myself like this?

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;
    }
}
like image 303
octopod Avatar asked May 02 '15 11:05

octopod


3 Answers

You will never benefit from duplicating code. This is premature optimization. A method call costs nothing, unless you perform it very often in a short while. In this case, it is acceptable to inline the code if it is not used in too many places of the system, but that is not your case.

Imagine that one day you add another feature to your class. If you inlined the code, you will have to update two constructors instead of a single one. All the bits of code which logic is related should be related in code (basically calling the same nethods/using the same classes). That's how you build reusable code.

Don't overthink about performance, first think about design, clarity and reusability. The parts of your system that really need to be performant are algorithmic ones, this should not impact the design.

like image 161
Dici Avatar answered Oct 29 '22 16:10

Dici


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();

    }

}

Javap output (javap -v Main.class) for pokus1.Main():

Do you see the invokespecial instruction on the offset 3? This is the call to pokus1.Main(int a,int b). So fundamentaly yes, it is more effective to not call the second constructor. But there are many optimizations in current JVM implementations, like method inlining, just-in-time compilation etc., so I think you doesn't need to think about it, otherwise you can think about every java call, if it is necessary.

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;
like image 27
Krab Avatar answered Oct 29 '22 15:10

Krab


Generally, there is no difference at all, because the just in time compiler inlines short methods.

Moreover, even if the code was not inlined, the overhead caused by the two branch instructions in machine code is unlikely to materially affect the runtime of the entire program, unless the program spends most of its time working with these vectors.

like image 5
meriton Avatar answered Oct 29 '22 17:10

meriton