【发布时间】:2013-02-07 17:20:11
【问题描述】:
我想知道使用 new BigInteger(String) 构造函数构造 BigInteger 对象的性能/复杂性。
考虑以下方法:
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 上的每个操作都会创建一个新操作,这是对大量数字的主要性能损失。
问题:
我错过了什么吗?
为什么会这样?
这个问题在最近的 JDK 中修复了吗?
还有其他选择吗?
更新:
我做了进一步的测量,我可以从一些答案中证实这一说法:
似乎BigInteger 已针对后续数值运算进行了优化,但代价是大量数字的更高构建成本,这对我来说似乎是合理的。
【问题讨论】:
-
看源代码似乎是合理的......
-
您是否使用非字符串构造函数进行了测量,我不确定操作是否会序列化-反序列化为字符串。
标签: java performance complexity-theory biginteger