我正在使用BigIntegers进行计算,该循环使用一个循环,该循环调用multiple()大约1000亿次,并且从BigInteger创建新对象的过程非常缓慢。我希望有人编写或找到了MutableBigInteger类。我在java.math包中找到了MutableBigInteger,但是它是私有的,当我将代码复制到新类中时,会出现很多错误,其中大多数我不知道如何解决。
像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倍。我想这真的归结为您需要乘以什么值。无论哪种方式,如果您将计算结果进行“
1000亿次”
问题内容: 我找到了一篇有趣的代码文章: 我真的很好奇了解创建此类的优势。我知道这里的此类对象是不可变的,因为一旦初始化就无法更改其变量值。我以前从未做过这样的事情,而且我真的不了解它的优势。 为什么是个好习惯? 您能说出可以使用这种方法的情况吗? 常量或只读变量呢?那不是很相似吗? 在文章中说,这不利于应用程序的性能。 但是为什么 呢? 问题答案: 您提到的示例是不可变对象。它在编程语言中被广泛
问题内容: 我在BigInteger的.Net项目Mono实现中使用(链接)。在Java中,我使用java.math.BigInteger。 相同的代码在Java中产生不同的结果。 .Net代码 Java代码。相同的inputBytes数组,相同的指数和模数,但结果不同。 我不明白为什么结果不同。 PS,例如,如果我使用InputBytes Java和.Net中的结果相同 魔术在哪里? 问题答案:
问题内容: 通过遵循所有Java标准,我的班级变得一成不变 这些是我在定义不可变类时所做的主要检查点。 但是还有一个问题,我的对象仍然可以通过java反射进行修改,对吗?还是我在课堂上错过了任何一点? 提前致谢。 问题答案: 没有什么可以躲藏的-即使是不可变的类也不能幸免。但是,您对此无能为力,因此“无法通过反射进行修改”不是不变性的标准之一。
描述 (Description) java.math.BigInteger.modPow(BigInteger exponent, BigInteger m)返回一个BigInteger,其值为(this exponent mod m)。 与pow不同,此方法允许负指数。 声明 (Declaration) 以下是java.math.BigInteger.modPow()方法的声明。 public
问题内容: 当我尝试获取Integer类型的输入时,我只需要做的就是下面的代码。 但是当涉及到BigInteger时,我不知道该怎么办。如何读取用户的BigInteger类型输入? 问题答案: 参考:Scanner#nextBigInteger
问题内容: 为了使一类不变,我可以做的是: 1)将类设为final 2)不提供设置器 3)将所有变量标记为final 但是,如果我的班级有另一个班级的另一个对象,那么somone可以更改该对象的值 问题答案: A)也使不可变 要么 B)不允许直接访问对象,而是仅提供获取器以充当代理。 编辑添加: 您 可以 制作一个深层副本并返回一个副本,而不是原始副本,但这通常不是您在Java中期望的行为类型。