Java 可变 BigInteger 类

标签 java performance precision biginteger mutable

我正在使用 BigIntegers 进行计算,它使用一个调用 multiply() 大约 1000 亿次的循环,而从 BigInteger 创建的新对象使它变得非常慢。我希望有人已经编写或找到了一个 MutableBigInteger 类。我在 java.math 包中找到了 MutableBigInteger,但它是私有(private)的,当我将代码复制到一个新类中时,出现了很多错误,其中大部分我都不知道如何修复。

像 MutableBigInteger 这样允许就地修改值的 Java 类有哪些实现?

最佳答案

他们是否有任何特殊原因使您不能使用反射来访问该类?

我能够毫无问题地这样做,这是代码:

public static void main(String[] args) throws Exception {       
    Constructor<?> constructor = Class.forName("java.math.MutableBigInteger").getDeclaredConstructor(int.class);
    constructor.setAccessible(true);
    Object x = constructor.newInstance(new Integer(17));
    Object y = constructor.newInstance(new Integer(19));
    Constructor<?> constructor2 = Class.forName("java.math.MutableBigInteger").getDeclaredConstructor(x.getClass());
    constructor2.setAccessible(true);
    Object z = constructor.newInstance(new Integer(0));
    Object w = constructor.newInstance(new Integer(0));

    Method m = x.getClass().getDeclaredMethod("multiply", new Class[] { x.getClass(), x.getClass()});
    Method m2 = x.getClass().getDeclaredMethod("mul", new Class[] { int.class, x.getClass()});
    m.setAccessible(true);
    m2.setAccessible(true);

    // Slightly faster than BigInteger
    for (int i = 0; i < 200000; i++) {
        m.invoke(x, y, z);
        w = z;
        z = x;
        x = w;
    }

    // Significantly faster than BigInteger and the above loop
    for (int i = 0; i < 200000; i++) {
        m2.invoke(x, 19, x);
    }

    BigInteger n17 = new BigInteger("17");
    BigInteger n19 = new BigInteger("19");
    BigInteger bigX = n17;

    // Slowest
    for (int i = 0; i < 200000; i++) {
        bigX = bigX.multiply(n19);
    }
}

编辑: 我决定尝试更多,看来 java.math.MutableBigInteger 的行为并不完全符合您的预期。

当你乘法时,它的操作不同,当它在分配给自己时必须增加内部数组的大小时,它会抛出一个很好的异常。我想有些事情是可以预料的。相反,我必须交换对象,以便它始终将结果放入不同的 MutableBigInteger。经过几千次计算后,反射的开销变得可以忽略不计。 MutableBigInteger 确实最终领先并随着操作数量的增加提供越来越好的性能。如果您使用带有整数基元的“mul”函数作为要乘以的值,MutableBigInteger 的运行速度几乎比使用 BigInteger 快 10 倍。我想这真的归结为你需要乘以什么值(value)。无论哪种方式,如果您使用 MutableBigInteger 的反射运行此计算“1000 亿次”,它的运行速度都会比 BigInteger 快,因为内存分配“更少”并且它会缓存反射操作,从而消除反射的开销。

关于Java 可变 BigInteger 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7863023/

相关文章:

java - 父构造函数调用的方法表现为子方法

Java:如何将参数传递给构造函数?未定义的方法错误?

java - 为heapsort优化堆结构

javascript - 我应该在 JavaScript 中使用大 switch 语句而不会出现性能问题吗?

performance - Python,迭代正则表达式但在第一次匹配时停止的最快方法

floating-point - 如何根据位数计算精度的十进制位数?

matlab - 按照我想要的格式设置数字

java - 如何从 Java 程序中获取 JVM 的最小和最大堆大小设置

math - float 学坏了吗?

java - SpringBoot应用程序忽略HibernateValidator的xml配置