我正在努力提高我在 Java 性能优化方面的知识,我尝试了多种方法来创建一个对象。
我遇到了这种我不熟悉的关于在类中使用 final 成员的行为:如果成员不是 final,则对象的创建要便宜得多(就时间而言)。它是正确的还是我的代码中存在一些缺陷?
没有最终成员的对象:
public class ComplexNumber {
private double re, im;
public ComplexNumber(double _re, double _im) {
re = _re;
im = _im;
}
public void setRe (double _re) {
re = _re;
}
public void setIm (double _im) {
im = _im;
}
@Override
public String toString() {
return re + " + i" + im;
}
@Override
public int hashCode() {
return 47 + 31*(int)re + 31*(int)im;
}
}
具有最终成员的对象:
public class FinalComplexNumber {
private final double re, im;
public FinalComplexNumber(double _re, double _im) {
re = _re;
im = _im;
}
@Override
public String toString() {
return re + " + i" + im;
}
@Override
public int hashCode() {
return 47 + 31*(int)re + 31*(int)im;
}
}
主类
public class PerformanceTest {
private static final long ITERATIONS = 100000000l;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
ComplexNumber nr = new ComplexNumber(0, 0);
System.out.println(nr);
long time = System.currentTimeMillis();
for (int i = 0; i < ITERATIONS; i++) {
ComplexNumber num = new ComplexNumber(i, i);
}
System.out.println(System.currentTimeMillis() - time);
time = System.currentTimeMillis();
for (int i = 0; i < ITERATIONS; i++) {
nr.setIm(i);
nr.setRe(i);
}
System.out.println(System.currentTimeMillis() - time);
time = System.currentTimeMillis();
for (int i = 0; i < ITERATIONS; i++) {
FinalComplexNumber num = new FinalComplexNumber(i, i);
}
System.out.println(System.currentTimeMillis() - time);
}
}
结果:
run:
0.0 + i0.0
953
219
7875
BUILD SUCCESSFUL (total time: 9 seconds)
最佳答案
the creation of an object is far less expensive (in terms of time) if the members are not final.
不,绝对不是这样。基本上,您的基准测试方法已损坏:
- 您正在使用
System.currentTimeMillis()
,这通常不是基准测试的好主意;System.nanoTime()
是测量elapsed 时间的首选 - 您没有提供任何 JIT 预热
- 您没有使用您创建的对象,这可能允许 JIT 优化,这在更普通的代码中是无效的
- 您甚至没有尝试从内存垃圾方面的公平竞争环境开始,因此您很可能会发现您的第一个循环不需要执行任何垃圾收集,但你的最后一个循环确实如此。
关于Java 在创建对象时的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30096339/