gpt4 book ai didi

performance - 使用 UnboxedSums 定义的 sum 类型是否比普通枚举更有效?

转载 作者:行者123 更新时间:2023-12-05 00:11:54 30 4
gpt4 key购买 nike

例如,这里是简单的 Haskell 枚举数据类型:

data Bool = False | True

-XUnboxedSums自 GHC-8.2.1 以来的扩展允许以更节省内存的方式定义和类型。这是文档中的引用:

In the degenerate case where all the alternatives have zero width, such as the Bool-like (# (# #) | (# #) #), the unboxed sum layout only has an Int32 tag field (i.e., the whole thing is represented by an integer).



我想知道,这种表示是否比使用简单的普通 Haskell 枚举数据类型更有效?

这是完整的文档:
  • https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#unboxed-sums
  • 最佳答案

    语义和表示
    这两种类型不能互换使用。
    方式

    data Bool = False | True
    是提升型。这意味着一个变量 x :: Bool仍然可以未评估(例如 thunk)。因此它将被表示为一个指针。
    相比之下
    (# (# #) | (# #) #)
    是 unlifted,并且真的只能有这两个值,并且将被表示为一个机器整数。
    空间效率
    但这并不意味着后者更节省空间:因为 TrueFalse是空构造函数(它们不带参数),它们在程序的静态代码中一劳永逸地存在,并且指针只是指向它们。所以在所有情况下成本都是一个机器字。
    运行时效率
    未装箱的变体可能比 Bool 稍微更有效:
  • 对于 Bool ,代码首先必须检查 this 是否已经评估过?,然后它可以分支到它是哪个构造函数。
    分支非常有效:代码不必遵循指针:指针地址的低几位中的“指针标签”将指示它是哪个构造函数。但是,掩蔽其他位会产生少量成本。
  • 在未装箱的变体中,它只是 01 ,并且不需要 thunk 检查。

  • 有朝一日可能是真的
    jberryman 说 :截至 2021 年 1 月,以下内容似乎尚未实现,但这就是某天可能发生的事情。
    数据类型的拆箱
    如果您定义这样的数据类型
    data Foo = Foo {-# UNPACK #-} !Bool
    你应该得到和你写的完全一样的结果
    data Foo = Foo (# (# #) | (# #) #)
    因为这是未装箱总和扩展的主要目的。
    在函数中拆箱
    如果你在 Bool 中定义了一个严格的函数论证,例如
    foo True = "Hello"
    foo False = "World!"
    然后我可以想象(但没有检查)编译器将其优化为一个接受 (# (# #) | (# #) #) 的 worker 。和一个负责 thunk 检查的包装器。然后包装器可能会内联在使用站点中 foo被使用,一切都可能以 (# (# #) | (# #) #) 告终.
    结论
    不要打扰。

    关于performance - 使用 UnboxedSums 定义的 sum 类型是否比普通枚举更有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52290702/

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