本文介绍了Java可变BigInteger类别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用BigIntegers进行计算,该计算使用一个循环,该循环调用multiple()大约1000亿次,并且BigInteger的新对象创建使其非常慢.我希望有人编写或找到了MutableBigInteger类.我在java.math包中找到了MutableBigInteger,但是它是私有的,当我将代码复制到新类中时,会出现很多错误,其中大多数我不知道如何解决.

I am doing calculations with BigIntegers that uses a loop that calls multiply() about 100 billion times, and the new object creation from the BigInteger is making it very slow. I was hoping somebody had written or found a MutableBigInteger class. I found the MutableBigInteger in the java.math package, but it is private and when I copy the code into a new class, many errors come up, most of which I don't know how to fix.

像MutableBigInteger这样的Java类存在哪些实现,可以实现就地修改值?

What implementations exist of a Java class like MutableBigInteger that allows modifying the value in place?

推荐答案

您是否有任何特殊原因无法使用反射来访问该类?

Is their any particular reason you cannot use reflection to gain access to the class?

我能够做到这一点而没有任何问题,这是代码:

I was able to do so without any problems, here is the code:

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的表现与您期望的不完全一样.

I decided to play around with a bit more, it does appear that java.math.MutableBigInteger doesn't behave exactly as you would expect.

乘以不同时,它的工作方式不同,并且在分配给自身时必须增加内部数组的大小时,它将引发一个异常.我猜是可以预料的.相反,我必须在对象周围进行交换,以便始终将结果放入另一个MutableBigInteger中.经过几千次计算,反射的开销可以忽略不计.随着操作数量的增加,MutableBigInteger最终会领先并提供越来越好的性能.如果您将"mul"函数与整数基元作为要乘以的值,则MutableBigInteger的运行速度将比使用BigInteger快10倍.我想这真的归结为您需要乘以什么值.无论哪种方式,如果您使用MutableBigInteger的反射将计算进行"1000亿次",它的运行速度都将比BigInteger快,这是因为内存分配更少",并且可以缓存反射操作,从而消除了反射的开销.

It operates differently when you multiply and it will throw a nice exception when it has to increase the size of the internal array when assigning to itself. Something I guess is fairly expected. Instead I have to swap around the objects so that it is always placing the result into a different MutableBigInteger. After a couple thousand calculations the overhead from reflection becomes negligible. MutableBigInteger does end up pulling ahead and offers increasingly better performance as the number of operations increases. If you use the 'mul' function with an integer primitive as the value to multiply with, the MutableBigInteger runs almost 10 times faster than using BigInteger. I guess it really boils down to what value you need to multiply with. Either way if you ran this calculation "100 billion times" using reflection with MutableBigInteger, it would run faster than BigInteger because there would be "less" memory allocation and it would cache the reflective operations, removing overhead from reflection.

这篇关于Java可变BigInteger类别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 10:46