使用bignums的开销

时间:2008-11-06 21:35:42

标签: language-features language-design

当涉及到数字时,我遇到了关于是否在我的语言中使用bignums作为默认数据类型的问题。我自己对此进行了评估,并将其降低到了方便性和舒适性与性能的关系。这个问题的答案取决于未经优化的程序中的性能影响程度。

在fixnum或整数足够的地方使用bignums的开销有多小?在最佳实施中它有多小?什么样的实现可以达到最小的开销,以及它们会产生什么样的额外权衡?

如果我将我的语言设置为bignums上的默认语言,我对整体语言表现的结果会有什么样的打击?

7 个答案:

答案 0 :(得分:4)

你也许可以看看Lisp是如何做到的。它几乎总是完全 正确的东西,并在必要时隐式转换类型。它有fixnums(“正常”整数),bignums,比率(减少适当分数表示为一组两个整数)和浮点数(不同大小)。只有浮点数具有精度误差,并且它们具有传染性,即一旦计算涉及浮点数,结果也是浮点数。 “Practical Common Lisp”对这种行为有很好的描述。

答案 1 :(得分:3)

说实话,最好的答案是“试试看”。

很明显,bignums不能像本机类型一样高效,后者通常适合单个CPU寄存器,但每个应用程序都不同 - 如果你的整数运算没有完全加载,那么开销可以忽略不计。< / p>

答案 2 :(得分:2)

来想一想......我认为它根本不会有很多性能打击。

因为bignums本质上会有一个非常大的基数,比如65536或更大的基数,通常是传统的fixnum和整数的最大可能值。

我不知道你设置bignum的基数有多大,但如果你设置得足够大,那么当它用来代替fixnums和/或整数时,它永远不会超过它的第一个bignum数字因此,操作几乎与普通的fixnums / int相同。

这为优化提供了机会,对于一个从未超过其第一个bignum-digit的bignum,你可以用超快速的一个bignum-digit操作替换它们。

然后在需要第二个bignum-digit时切换到n位数算法。

这可以通过位标志和所有算术运算的验证操作来实现,粗略思考,如果数据块的最高位设置为0,则可以使用最高位来表示bignum,然后处理它们好像它们是正常的fixnum / int,但是如果它被设置为1,则将块解析为bignum结构并从那里使用bignum算法。

这应该避免来自简单循环迭代器变量的性能命中,我认为这是第一个可能的性能命中源。

这只是我的粗略思考,因为你应该比我知道更好的建议: - )

P.S。抱歉,忘记了bignum-digit和bignum-base的技术术语

答案 3 :(得分:0)

您的缩减是正确的,但选择取决于您的语言的性能特征,我们无法知道

一旦实现了语言,就可以衡量性能差异,并为程序员提供选择默认语言的指令

答案 4 :(得分:0)

在创建自己的基准测试之前,您永远不会知道实际的性能影响,因为结果会因语言,语言版本和每个cpu而异。除了明显的事实是32位整数使用两倍于16位整数的内存之外,没有与语言无关的方法来衡量这一点。

答案 5 :(得分:0)

  

在fixnum或整数足够的地方使用bignums的开销有多小?显示小可以最好实现吗?

坏消息是即使在最好的软件实现中,BigNum也会比内置算法慢几个数量级(即从因子10到因子1000的所有内容)。

我没有确切的数字,但我不认为确切的数字在这种情况下会有很大帮助:如果你需要大数字,请使用它们。如果没有,不要。如果您的语言默认使用它们(哪种语言可以使用?某些动态语言会...),请考虑切换到另一种语言的缺点是否可以通过性能提升来补偿(很少应该这样做)。

(这大致可以转化为:有一个巨大的差异,但它不应该重要。如果(并且只有)重要,请使用另一种语言,因为即使有最好的实施,这语言显然不适合这项任务。)

答案 6 :(得分:0)

我完全怀疑它是否值得,除非它是特定于域的。

首先想到的是整个程序中的 for for循环,所有的小迭代器变量都是bignums吗?那太吓人了!

但如果你的语言相当实用......那么也许不是。