我需要一些复杂数学库,所以我在使用不可变的复数和可变的复数的库之间犹豫不决。显然,我希望计算速度相对较快(除非它会影响可读性等)。
因此,我创建了一个简单的可变与不可变速度测试:
final class MutableInt {
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public MutableInt() {
this(0);
}
public MutableInt(int value) {
this.value = value;
}
}
final class ImmutableInt {
private final int value;
public ImmutableInt(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
public class TestImmutableSpeed {
static long testMutable(final int arrLen) {
MutableInt[] arrMutable = new MutableInt[arrLen];
for (int i = 0; i < arrMutable.length; ++i) {
arrMutable[i] = new MutableInt(i);
for (int j = 0; j < arrMutable.length; ++j) {
arrMutable[i].setValue(arrMutable[i].getValue() + j);
}
}
long sumMutable = 0;
for (MutableInt item : arrMutable) {
sumMutable += item.getValue();
}
return sumMutable;
}
static long testImmutable(final int arrLen) {
ImmutableInt[] arrImmutable = new ImmutableInt[arrLen];
for (int i = 0; i < arrImmutable.length; ++i) {
arrImmutable[i] = new ImmutableInt(i);
for (int j = 0; j < arrImmutable.length; ++j) {
arrImmutable[i] = new ImmutableInt(arrImmutable[i].getValue() + j);
}
}
long sumImmutable = 0;
for (ImmutableInt item : arrImmutable) {
sumImmutable += item.getValue();
}
return sumImmutable;
}
public static void main(String[] args) {
final int arrLen = 1<<14;
long tmStart = System.nanoTime();
System.out.println("sum = " + testMutable(arrLen));
long tmMid = System.nanoTime();
System.out.println("sum = " + testImmutable(arrLen));
long tmEnd = System.nanoTime();
System.out.println("speed comparison mutable vs immutable:");
System.out.println("mutable " + (tmMid - tmStart)/1000000 + " ms");
System.out.println("immutable " + (tmEnd - tmMid)/1000000 + " ms");
}
}
您可以调整数组大小,以使测试运行速度过慢/过快。我使用以下参数运行:-server -Xms256m -XX:+AggressiveOpts 结果如下:
sum = 2199023247360 sum = 2199023247360 可变与不可变的速度比较: 可变 102 毫秒 不可变 1506 毫秒 问题是:我是否缺少某些优化参数,或者不可变版本确实比可变版本慢15倍?
如果是这样,为什么会有人在数学库中编写包含不可变类 Complex 的代码?不可变只是“时髦”但无用吗?
我知道不可变类作为哈希映射键或不能存在竞争条件时更安全,但这些都是可以处理任何地方的特殊情况。