Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的高效BigInteger_Java_Biginteger - Fatal编程技术网

Java中的高效BigInteger

Java中的高效BigInteger,java,biginteger,Java,Biginteger,我们在产品中有一组位置,其中需要BigInteger,因为数字可能相当长。然而,在超过90%的情况下,它们实际上并没有那么长,可以很容易地用一个较长的长度来控制 从BigInteger的实现来看,如果使用BigInteger的长度足够长,那将是相当浪费的 创建一个具有BigInteger(除法、乘法等)等函数的接口,并由BigInteger的子类和一个包装为Long的类实现,这有意义吗?比如: Interface: EfficientBigInteger Class 1: MyBigIntege

我们在产品中有一组位置,其中需要BigInteger,因为数字可能相当长。然而,在超过90%的情况下,它们实际上并没有那么长,可以很容易地用一个较长的长度来控制

从BigInteger的实现来看,如果使用BigInteger的长度足够长,那将是相当浪费的

创建一个具有BigInteger(除法、乘法等)等函数的接口,并由BigInteger的子类和一个包装为Long的类实现,这有意义吗?比如:

Interface: EfficientBigInteger
Class 1: MyBigInteger extends BigInteger imlpements EfficientBigInteger
Class 2: MyLong implements EfficientBigInteger (this will contain a Long, as we cannot extend the Long class)
也许我们走错方向了

谢谢, 你


更新:这些对象(Long或BigInteger)存储在内存中相当长一段时间,因为它们帮助我们识别与之交互的系统的问题行为。因此,内存占用可能是一个问题。这是我们试图避免的问题。BigInteger类有几个字段(signum、mag array、bitcount等),这些字段加起来大约是封装Long的类的两倍(首先考虑到拥有对象的内存成本)。这意味着我们经常使用的东西的占地面积增加了一倍。

你必须对这些值进行算术运算吗?因为如果你这样做了,那么一个开始是长的可能会变成一个大整数,这听起来很痛苦:你必须在每一个算术运算之前进行一个测试,它可能会超过MAX_long。好吧,我想你可以在包装器类中封装所有这些。与BigInteger类在1或2个元素的数组中循环所需的时间相比,测试溢出需要多少时间

如果您不做算术,那么使用long函数所节省的成本将是最小的。你在用BigInteger做什么,只是把它读入并写出?在这种情况下,几乎肯定不值得这么麻烦

就我个人而言,这是我很想自己做的事情,我理解你的想法。但我会退一步说:性能真的是个问题吗?我们到底做了多少算术?我们将获得多少性能增益?是否值得增加程序的复杂性并可能引入bug


除非您有理由相信性能确实是一个问题,并且这样做会产生显著的影响,否则我不会。大约在1986年,我为Cobol编译器实现了这样一个东西。这对性能没有任何影响:决定是否适合long,然后将其转换为long,然后再转换回long的开销等于节省时间。

如何检测涉及long的操作的溢出?是否存在性能问题,您是否对应用程序进行了分析,以确保它来自对小的大整数的操作?如果不是,您正在试图过早地进行优化。一个大整数的值适合
long
实际上并不比单个
long
值占用更多的空间-它有一个
long
数组(大小为1)。如果没有集成到虚拟机中(就像一些smalltalk虚拟机那样),那么在它们之间拥有单独的类和实现算法是非常复杂的。@Vinet reynolds-我们可以在代码中添加大量检查,这将花费CPU而不是内存(请记住,内存也会消耗CPU)@jb nizet我们不这么认为,因为我们过去遇到过许多与内存相关的性能问题,这些问题促使我们尽可能减少内存使用。引入错误是可能的,但鉴于此代码仅限于几个类,我们可以积极地对其进行单元测试,直到我们确定它工作正常为止。测试溢出的CPU负载预计不是一个大问题,因为我们很少对这些值进行算术运算。就性能增益而言,我们的计算表明BigInteger占用的内存量是封装Long的类的两倍。如果这是真的,并且我们存储了许多大整数,那么这里可能会有相当大的内存占用。当然,如果您足够努力,您可以对代码的正确性有很高的信心。我的观点是:这值得付出努力吗?而且:无论你多么努力,总有一个非零的可能性,一个微妙的错误,使其生产。如果是为了一个能为应用程序增加价值的函数,那么生活就是这样。但是,如果只是一时兴起,为什么还要增加风险呢?至于内存,通过快速查看源代码,我认为一个BigInteger需要32个字节加上对象开销来存储一个适合长时间存储的数字,所以当然,它需要更多的内存。但是,你的记忆中有数百万个这样的东西吗?如果你有几百个,你可能会“浪费”好几k。如果你真的必须持有数百万张,或者你处在一个高度受限的环境中,也许这是值得的。如果不是,那么,在现代桌面上,一兆字节算不了什么。谁在乎呢?我自己非常关心优化,我讨厌浪费内存或CPU周期。但你不想为此疯狂。进一步思考:如果内存是个问题,那么你一次在内存中有多少个数字?如果是一打,那么一个新的类定义占用的内存可能会超过一打BigInteger占用的内存。如果你有数以百万计的数字,问题可能不是每个数字都太大,而是你在内存中保存了太多。我不知道你的应用程序是什么,但也许你可以用这些数字来分析我们使用的设备中某些元素的行为,而不是“读取所有内容,然后进行处理”。计算方法是:设备中的每个子元素都有30-40个整数。每个设备最多有20个子元件。该系统设计用于处理多达1000台设备。这就是80万个整数。开销大约是30MB,对吗?如果是这样,那就不是什么大问题,你说得很对。