我注意到,在使用Java的BigInteger类时,即使使用相同的数字和操作,基本算术运算似乎也比原始运算效率低。使用数字的BI表示的算法比使用相同数字的长表示的完全相同的算法在天文学上花费更多的时间。
为了说明我的意思,我提供了一个有效的代码示例。在下面的示例中,我简单地遍历1和1000000000之间的所有整数,在每次迭代时执行mod 2操作,然后打印出循环的总运行时间。我首先使用long,然后使用BigInteger:
import java.math.BigInteger;
public class FunWithNumbers {
public static void main(String[] args) {
long myNumL = 100000000L; // Long representation of some number n
BigInteger myNumB = new BigInteger("100000000"); // BI representation of same number
/* long version */
long startTime = System.nanoTime();
for (long i=1L; i<= myNumL; i++) {
long a = myNumL % 2;
}
System.out.println("Total computation time (long representation): " +
(System.nanoTime() - startTime)*Math.pow(10, -9) + " seconds.");
/* BI version */
startTime = System.nanoTime();
BigInteger index = new BigInteger("1");
while (!index.equals(myNumB)) {
BigInteger b = myNumB.remainder(index);
index = index.add(BigInteger.ONE);
}
System.out.println("Total computation time (BI representation): " +
(System.nanoTime() - startTime)*Math.pow(10, -9) + " seconds.");
}
}
这会生成以下输出:
总计算时间(长表示):0.035671096秒。
总计算时间(BI表示):7.031978092秒。
正如您所看到的,运行时间甚至无法进行远程比较。我的问题是我需要使用太大而不适合“长”数据类型的数字。
有没有办法恢复原始算术的效率,仍然能够使用超过最大长度的任意大数?
如果需要,我可以切换到另一种语言;我绝不会被Java所束缚。
答案 0 :(得分:2)
我建议你尝试使用C或C ++。有各种C / C ++库可以有效地执行更大的整数运算。例如,我遇到了一个看起来很有希望的“ttmath”。
BigInteger
的效率问题的很大一部分是它使用不可变对象对数字建模。因此,每个大的算术运算都会导致创建一个新的BigInteger
。
答案 1 :(得分:0)
有没有办法取回原始算法的效率 仍然可以使用超过的任意大数 最大长度?
不。如果是Java。
答案 2 :(得分:-1)
如果您不需要确切的答案,请考虑加倍。它具有宽范围和非常快速的算术,代价仅代表53个有效位。