如何在 Haskell 中使用未装箱的类型
How to operate with unboxed types in Haskell
对于 Int、Float 等,有未装箱的类型 GHC。
我知道基于它们构建的代码可以减少 运行 开销,
但我没有看到如何输入和输出数据的方法 to/from 一个基于未装箱 Int 的函数,即
GHC.Exts 定义函数 (+#) 和 (*#),但我找不到函数 boxing/unboxy
readInt:: String -> Int#
showInt:: Int# -> String
boxInt :: Int# -> Int
unboxInt :: Int -> Int#
实例 Show Int# 和实例 Read Int# 不能存在,因为 show 和 read 是多态的。
如果没有这些功能,我如何将未装箱类型的优化代码块与其余应用程序集成?
Int
、Float
等只是 GHC 中的 data
类型:
data Int = I# Int#
data Float = F# Float#
-- etc.
构造函数仅由 GHC.Exts
导出。导入它并使用构造函数转换:
{-# LANGUAGE MagicHash #-}
import GHC.Exts
main = do I# x <- readLn
I# y <- readLn
print (I# (x +# y))
I know about code built on them is running with less overhead
虽然这在某种意义上是正确的,但您通常不必担心。 GHC 非常努力地优化内置类型的框,我希望它在大多数情况下都能做得很好,您也可以手动进行操作。
在实践中,您更应该注意的是确保
- 它实际上看到了它知道未装箱形式的具体
Int
或 Float
类型。特别是,这 不 对多态函数起作用(多态性通常依赖于框,就像在 OO 语言中一样)。
如果您希望一个函数是多态的并且使用原始类型仍然 运行 快速,请确保添加 SPECIALIZE
注释 and/or 重写规则。
- 懒惰不会成为阻碍。未装箱的类型始终是严格的,因此严格性注释可以使 GHC 更容易删除箱子。
当然还有分析您的代码。
只有当你真的确定你想要它时(例如,确保当一个新的 GHC 以不同方式优化时,方框不会重新出现),或者如果如果您真的手动访问未装箱的原始类型,您想要获取 SIMD 指令。
对于 Int、Float 等,有未装箱的类型 GHC。 我知道基于它们构建的代码可以减少 运行 开销, 但我没有看到如何输入和输出数据的方法 to/from 一个基于未装箱 Int 的函数,即
GHC.Exts 定义函数 (+#) 和 (*#),但我找不到函数 boxing/unboxy
readInt:: String -> Int#
showInt:: Int# -> String
boxInt :: Int# -> Int
unboxInt :: Int -> Int#
实例 Show Int# 和实例 Read Int# 不能存在,因为 show 和 read 是多态的。
如果没有这些功能,我如何将未装箱类型的优化代码块与其余应用程序集成?
Int
、Float
等只是 GHC 中的 data
类型:
data Int = I# Int#
data Float = F# Float#
-- etc.
构造函数仅由 GHC.Exts
导出。导入它并使用构造函数转换:
{-# LANGUAGE MagicHash #-}
import GHC.Exts
main = do I# x <- readLn
I# y <- readLn
print (I# (x +# y))
I know about code built on them is running with less overhead
虽然这在某种意义上是正确的,但您通常不必担心。 GHC 非常努力地优化内置类型的框,我希望它在大多数情况下都能做得很好,您也可以手动进行操作。
在实践中,您更应该注意的是确保
- 它实际上看到了它知道未装箱形式的具体
Int
或Float
类型。特别是,这 不 对多态函数起作用(多态性通常依赖于框,就像在 OO 语言中一样)。
如果您希望一个函数是多态的并且使用原始类型仍然 运行 快速,请确保添加SPECIALIZE
注释 and/or 重写规则。 - 懒惰不会成为阻碍。未装箱的类型始终是严格的,因此严格性注释可以使 GHC 更容易删除箱子。
当然还有分析您的代码。
只有当你真的确定你想要它时(例如,确保当一个新的 GHC 以不同方式优化时,方框不会重新出现),或者如果如果您真的手动访问未装箱的原始类型,您想要获取 SIMD 指令。