性能:我应该避免构造函数委托吗?
Performance: Should I avoid constructor delegation?
我想知道构造函数中的运行构造函数(又名构造函数委托)和非.
请不要将此问题解释为我支持冗余,例如复制长构造函数以提高性能。我知道在大多数情况下,出于性能以外的许多原因,在构造函数中调用构造函数是可取的。 (例如可读性)
例如,这是我最近创建的 Vector3D
class:
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;
}
}
不调用 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;
}
}
您永远不会从复制代码中获益。这是过早的优化。方法调用不需要任何成本,除非您在短时间内非常频繁地执行它。在这种情况下,如果系统中使用的地方不是太多,内联代码是可以接受的,但你的情况不是这样。
想象一下,有一天您向 class 添加了另一项功能。如果内联代码,则必须更新两个构造函数而不是一个构造函数。逻辑相关的所有代码位都应该在代码中相关(基本上调用相同的 nethods/using 相同的 classes)。这就是您构建可重用代码的方式。
不要过度考虑性能,首先要考虑设计、清晰度和可重用性。系统中真正需要高性能的部分是算法部分,这不应该影响设计。
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 输出 (javap -v Main.class) for pokus1.Main():
你看到偏移3
上的invokespecial
指令了吗?这是对 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;
一般来说,完全没有区别,因为the just in time compiler inlines short methods.
此外,即使代码没有被内联,由机器代码中的两条分支指令引起的开销也不太可能对整个程序的运行时间产生实质性影响,除非程序将大部分时间花在处理这些向量上.
我想知道构造函数中的运行构造函数(又名构造函数委托)和非.
请不要将此问题解释为我支持冗余,例如复制长构造函数以提高性能。我知道在大多数情况下,出于性能以外的许多原因,在构造函数中调用构造函数是可取的。 (例如可读性)
例如,这是我最近创建的 Vector3D
class:
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;
}
}
不调用 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;
}
}
您永远不会从复制代码中获益。这是过早的优化。方法调用不需要任何成本,除非您在短时间内非常频繁地执行它。在这种情况下,如果系统中使用的地方不是太多,内联代码是可以接受的,但你的情况不是这样。
想象一下,有一天您向 class 添加了另一项功能。如果内联代码,则必须更新两个构造函数而不是一个构造函数。逻辑相关的所有代码位都应该在代码中相关(基本上调用相同的 nethods/using 相同的 classes)。这就是您构建可重用代码的方式。
不要过度考虑性能,首先要考虑设计、清晰度和可重用性。系统中真正需要高性能的部分是算法部分,这不应该影响设计。
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 输出 (javap -v Main.class) for pokus1.Main():
你看到偏移3
上的invokespecial
指令了吗?这是对 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;
一般来说,完全没有区别,因为the just in time compiler inlines short methods.
此外,即使代码没有被内联,由机器代码中的两条分支指令引起的开销也不太可能对整个程序的运行时间产生实质性影响,除非程序将大部分时间花在处理这些向量上.