有未装箱的类型GHC,用于Int,Float等。 我知道基于它们构建的代码以更少的开销运行, 但我看不到如何基于未装箱的 Int 向/从函数输入和输出数据的方法,即
全康。Exts 定义了函数 (+#( 和 (*#(,但我找不到函数 boxing/unboxy
readInt:: String -> Int#
showInt:: Int# -> String
boxInt :: Int# -> Int
unboxInt :: Int -> Int#
实例显示 Int# 和实例读取 Int# 不能存在,因为显示和读取多态。
如果没有这些功能,我如何将未装箱类型的优化代码块与应用程序的其余部分集成在一起?
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))
基于它们构建的代码以更少的开销运行
虽然这在某种意义上是正确的,但您通常不应该担心。GHC非常努力地优化内置类型的盒子,我希望它在大多数情况下也能做得很好,你也可以手动做到这一点。
在实践中,你应该更加小心的是确保
- 它实际上看到它知道未装箱形式的具体
Int
或Float
类型。特别是,这不适用于多态函数(多态性通常依赖于盒子,就像在 OO 语言中一样(。
如果希望函数是多态的,并且仍然使用基元类型快速运行,请确保添加SPECIALIZE
注释和/或重写规则。 - 这种懒惰并不妨碍。未装箱的类型始终是严格的,因此严格性注释可以使 GHC 更容易删除箱子。
当然,还要分析您的代码。
只有当您真正确定需要它时(例如,确保当新的 GHC 以不同的方式优化时,盒子不会重新出现(,或者如果您想获取 SIMD 指令,您才应该实际手动访问未装箱的基元类型。