gpt4 book ai didi

haskell - `Integer` 与 `Int64` 与 `Word64`

转载 作者:行者123 更新时间:2023-12-03 11:01:20 27 4
gpt4 key购买 nike

我有一些数据可以用无符号 Integral 表示类型,其最大值需要 52 位。仅 AFAIK Integer , Int64Word64满足这些要求。

我能找到的关于这些类型的所有信息是 Integer已签名并具有 float 无限位大小,Int64Word64分别是固定的、有符号的和无符号的。我找不到的是有关这些类型的实际实现的信息:

  • 如果存储为 Integer,52 位值实际占用多少位? ?
  • 我是否正确 Int64Word64允许您存储 64 位数据并为任何值精确加权 64 位?
  • 这些类型中的任何一个是否由于大小以外的任何其他原因而更具性能或更可取,例如 native 代码实现或直接处理器指令相关的优化?
  • 以防万一:您会推荐哪一个来在性能极其敏感的应用程序中存储 52 位值?
  • 最佳答案

    How many bits will a 52-bit value actually occupy if stored as an Integer?



    这取决于实现。使用 GHC,适合机器字的值直接存储在 Integer 的构造函数中。 ,所以如果你在 64 位机器上,它应该占用与 Int 相同的空间量。这对应于 S# Integer 的构造函数:
    data Integer = S# Int#
    | J# Int# ByteArray#

    较大的值(即用 J# 表示的值)存储在 GMP 中.

    Am I correct that Int64 and Word64 allow you to store a 64-bit data and weigh exactly 64 bits for any value?



    不完全——它们是盒装的。一个 Int64实际上是指向未评估的 thunk 的指针或指向信息表的单字指针加上 64 位整数值。 (参见 GHC commentary 了解更多信息。)

    如果您真的想要保证为 64 位的东西,没有异常(exception),那么您可以使用未装箱的类型,如 Int64# ,但我强烈建议先进行分析;未装箱的值使用起来非常痛苦。例如,你不能使用未装箱的类型作为类型构造函数的参数,所以你不能有 Int64# 的列表。 s。您还必须使用特定于未装箱整数的操作。当然,所有这些都是 GHC 特有的。

    如果您希望存储大量 52 位整数,您可能需要使用 vectorrepa (基于向量,具有自动并行等花哨的东西);它们在后台存储未装箱的值,但让您以装箱的形式使用它们。 (当然,您取出的每个单独的值都会被装箱。)

    Are any of those types more performant or preferrable for any other reasons than size, e.g. native code implementations or direct processor instructions-related optimizations?



    是的;使用 Integer每次操作都会产生一个分支,因为它必须区分机器字和大数情况;当然,它必须处理溢出。固定大小的整数类型避免了这种开销。

    And just in case: which one would you recommend for storing a 52-bit value in an application extremely sensitive in terms of performance?



    如果您使用的是 64 位机器: Int64或者,如果必须的话, Int64# .

    如果您使用的是 32 位机器:可能是 Integer , 因为在 32 位 Int64使用对 GHC 函数的 FFI 调用进行模拟,这些函数可能不是高度优化的,但我会尝试两者并对其进行基准测试。与 Integer ,您将在小整数上获得最佳性能,并且 GMP 进行了高度优化,因此它在较大整数上的表现可能比您想象的要好。

    您可以在 Int64 之间进行选择和 Integer在编译时使用 C 预处理器(通过 {-# LANGUAGE CPP #-} 启用);我认为让Cabal 控制 #define 很容易。基于目标架构的字宽。当然,请注意它们并不相同。您必须小心避免 Integer 中的“溢出”。代码,例如 Int64Bounded 的一个实例但是 Integer不是。最简单的方法可能是只针对单个字宽(以及类型)来提高性能,而在另一个方面则表现较慢。

    我建议创建自己的 Int52键入 newtype包装 Int64 , 或 Word52包装 Word64 — 只需选择与您的数据更匹配的那个,应该不会对性能产生影响;如果只是任意位,我会选择 Int64 , 只是因为 IntWord 更常见.

    您可以定义所有实例以自动处理包装(尝试在 GHCi 中使用 :info Int64 以找出您要定义的实例),并提供直接在 newtype 下应用的“不安全”操作。对于您知道不会有任何溢出的性能关键情况。

    然后,如果您不导出 newtype构造函数,你可以随时交换 Int52 的实现稍后,无需更改任何其余代码。不用担心单独类型的开销 — newtype 的运行时表示与底层类型完全一致;它们只存在于编译时。

    关于haskell - `Integer` 与 `Int64` 与 `Word64`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8873000/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com