我有一些数据可以用无符号Integral类型表示,其最大值需要52位.仅限AFAIK Integer,Int64并Word64满足这些要求.
我可以找到关于这些类型的所有信息Integer都是签名的并且具有浮动的无限位大小,Int64并且Word64分别是固定的,有符号和无符号的.我不知道的是有关这些类型的实际实施的信息:
如果存储为Integer?,52位值实际占用多少位?
我是否正确,Int64并Word64允许您存储64位数据,并为任何值权重64位?
这些类型中的任何一种是否因大小等原因而更具性能或优先性,例如本机代码实现或直接处理器指令相关的优化?
以防万一:您建议将哪一个存储在一个对性能极为敏感的应用程序中的52位值?
ehi*_*ird 22
如果存储为
Integer?,52位值实际占用多少位?
这取决于实现.对于GHC,适合机器字的值直接存储在构造函数中Integer,因此如果您使用的是64位计算机,则它应占用与Int相同的空间量.这对应于以下S#构造函数Integer:
data Integer = S# Int#
| J# Int# ByteArray#
Run Code Online (Sandbox Code Playgroud)
较大的值(即用其表示的值J#)与GMP一起存储.
我是否正确,
Int64并Word64允许您存储64位数据,并为任何值权重64位?
不完全 - 他们是盒装的.一个Int64实际上是一个指针到任何一个未计算的形实转换或一个字指针,一个信息表加上一个64位整数值.(有关更多信息,请参阅GHC评论.)
如果你真的想要保证64位的东西,没有例外,那么你可以使用类似的未装箱类型Int64#,但我强烈建议先进行分析; 未装箱的值使用起来非常痛苦.例如,您不能使用未装箱的类型作为类型构造函数的参数,因此您不能拥有Int64#s 的列表.您还必须使用特定于未装箱整数的操作.当然,所有这些都是GHC特有的.
如果你正在寻找存储大量的52位整数,你可能需要使用矢量或repA的(内置矢量,并具有自动并行花哨的东西); 它们将未装箱的值存储在引擎盖下,但让您以盒装形式使用它们.(当然,您取出的每个单独的价值都将被装箱.)
这些类型中的任何一种是否因大小等原因而更具性能或优先性,例如本机代码实现或直接处理器指令相关的优化?
是; Integer因为它必须区分机器词和bignum案件,所以使用每个操作都会产生一个分支; 当然,它必须处理溢出.固定大小的整数类型避免了这种开销.
以防万一:您建议将哪一个存储在一个对性能极为敏感的应用程序中的52位值?
如果您使用的是64位计算机:Int64或者,如果您必须使用,Int64#.
如果您正在使用32位计算机:可能Integer,因为在32位Int64上使用FFI调用GHC函数进行模拟,这些函数可能没有经过高度优化,但我会尝试两者并对其进行基准测试.有了Integer,你将获得小整数的最佳性能,并且GMP经过了大量优化,所以它可能比你想象的更大.
您可以使用C预处理器(启用时)在编译时Int64和Integer编译时进行选择{-# LANGUAGE CPP #-}; 我认为让Cabal #define根据目标架构的字宽控制一个很容易.当然要注意它们不一样; 你必须小心避免Integer代码中的"溢出" ,例如Int64是一个Bounded但Integer不是的实例.最简单的方法是只针对单个字宽(从而键入)以获得性能,并使用较慢的性能来生活.
我建议创建自己的Int52类型作为newtype包装器Int64或Word52包装器Word64- 只需选择与您的数据匹配的更好,不应该对性能产生影响; 如果它只是随意的位,我Int64只会因为Int比它更常见Word.
您可以定义所有实例来自动处理包装(尝试:info Int64在GHCi中找出您要定义的实例),并提供"不安全"操作,这些操作只适用newtype于您知道赢得的性能关键情况下任何溢出.
然后,如果不导出newtype构造函数,则可以随时交换Int52后续实现,而无需更改任何其余代码.不要担心单独类型的开销 - a的运行时表示newtype与底层类型完全相同; 它们只存在于编译时.
| 归档时间: |
|
| 查看次数: |
3205 次 |
| 最近记录: |