我想知道使用构造函数构造 BigInteger对象的性能/复杂性。new BigInteger(String)
考虑以下方法:
public static void testBigIntegerConstruction()
{
for (int exp = 1; exp < 10; exp++)
{
StringBuffer bigNumber = new StringBuffer((int) Math.pow(10.0, exp));
for (int i = 0; i < Math.pow(10.0, exp - 1); i++)
{
bigNumber.append("1234567890");
}
String val = bigNumber.toString();
long time = System.currentTimeMillis();
BigInteger bigOne = new BigInteger(val);
System.out.println("time for constructing a 10^" + exp
+ " digits BigInteger : " + ((System.currentTimeMillis() - time))
+ " ms");
}
}
此方法在开始时创建带有数字BigInteger
的字符串对象,并且随着每次迭代而增加。它测量并输出构造相应对象所需的时间。10^x
x=1
BigInteger
在我的机器(Intel Core i5 660,JDK 6 Update 25 32 位)上,输出为:
time for constructing a 10^1 digits BigInteger : 0 ms
time for constructing a 10^2 digits BigInteger : 0 ms
time for constructing a 10^3 digits BigInteger : 0 ms
time for constructing a 10^4 digits BigInteger : 16 ms
time for constructing a 10^5 digits BigInteger : 656 ms
time for constructing a 10^6 digits BigInteger : 59936 ms
time for constructing a 10^7 digits BigInteger : 6227975 ms
虽然忽略高达 10^5 的行(由于(处理器)缓存效果、JIT 编译等可能引入的失真),但我们可以清楚地看到 O(n^2) 的复杂性。请记住,BigInteger
由于不变性,对 a 的每个操作都会创建一个新的操作,这是对大量数字的主要性能惩罚。
问题:
我错过了什么?
为什么会这样?
这在最近的 JDK 中修复了吗?
有没有其他选择?
更新:
我做了进一步的测量,我可以从一些答案中证实这一说法:
这似乎BigInteger
针对后续的数值运算进行了优化,但代价是大量数字的更高建造成本,这对我来说似乎是合理的。