haskell - 为什么使用 UNPACK 和严格标记记录字段很常见?
问题描述
我注意到这种模式在 Haskell 库中很常见:
data Foo = Foo { field :: {-# UNPACK #-} !Sometype }
例如UNPACK
,输入字段的类型并使其严格。
我了解 pragma 和 annotation 的作用,但我不明白为什么它如此普遍:我在 Haskell 中编程已有 15 年,很少使用严格注释,也从未使用UNPACK
pragma。
如果这个成语这么有用,为什么不让它不那么“丑”呢?
解决方案
pragma 可能有点丑陋,但它避免了其他地方更多的丑陋。当性能至关重要时,程序员通常需要为数据构造函数选择特定的形状。假设我有
data Point = Point Int Int
data Segment = Segment Point Point
这很符合逻辑,但它有一堆额外的间接性:一个Segment
由七个堆对象组成。如果我正在处理很多细分市场,那就太糟糕了。
我可以用手压扁这个单位:
data Segment = Segment Int# Int# Int# Int#
但是现在我已经忘记了数字代表点的事实,并且我对段所做的一切都必须涉及相当不方便和奇怪的未装箱操作。
幸运的是,有一个更好的方法:
-- The small strict Int fields will be unpacked by default
-- with any reasonably recent GHC version.
data Point = Point !Int !Int
data Segment = Segment {-# UNPACK #-} !Point {-# UNPACK #-} !Point
这仍然给我每个段一个堆对象,但我可以使用Point
s 和Int
s 并且(通常)依赖编译器很好地拆箱。
推荐阅读
- jquery - 如何从动态填充的表格中获取可点击单元格的数据
- amazon-web-services - 当消息被添加到 SQS 时,仅向 lambda 发送事件主体而不是整个事件
- ios - 我如何知道 NFC 护照芯片读取了哪个数据组?
- node.js - npm package.json 别名,例如 webpack
- python - 理解将月份名称映射到其数值的字典
- c# - 如何从自定义基础项目创建 ASP.NET Core MVC 样板
- django - django,在过滤器中遍历多个表(模型)
- react-native - 在 React Native Navigation 中的选项卡之间切换时如何保持堆叠的屏幕
- flutter - FLUTTER:如何制作模糊的文字?
- c# - C#中类变量和实例变量的区别