gpt4 book ai didi

optimization - Haskell 平台 : nested functions and optimization

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

在 haskell 平台中实现许多功能时有一个非常常见的模式让我很困扰,但我找不到解释。这是关于使用嵌套函数进行优化。

where 子句中的嵌套函数旨在进行尾递归的原因对我来说非常清楚(如 length ),但是当内部函数与顶级函数具有完全相同的类型时,目的是什么?例如,它发生在 Data.Set module 的许多函数中。 ,像下面这样:

-- | /O(log n)/. Is the element in the set?
member :: Ord a => a -> Set a -> Bool
member = go
where
STRICT_1_OF_2(go)
go _ Tip = False
go x (Bin _ y l r) = case compare x y of
LT -> go x l
GT -> go x r
EQ -> True
#if __GLASGOW_HASKELL__ >= 700
{-# INLINABLE member #-}
#else
{-# INLINE member #-}
#endif

我怀疑这可能与内存有关,但我不确定。

编辑 : 由于 dave4420 表示严格,这里是 STRICT_1_OF_2 的定义可以在同一模块中找到的宏:
-- Use macros to define strictness of functions.
-- STRICT_x_OF_y denotes an y-ary function strict in the x-th parameter.
-- We do not use BangPatterns, because they are not in any standard and we
-- want the compilers to be compiled by as many compilers as possible.
#define STRICT_1_OF_2(fn) fn arg _ | arg `seq` False = undefined

我明白这个宏是如何工作的,但是我仍然不明白为什么 go连同 STRICT_1_OF_2(go)不应在顶层移动以代替 member .

也许不是因为优化,而仅仅是因为风格选择?

编辑 2 : 我加了 INLINABLEINLINE设置模块的一部分。乍一看,我没想到他们可能与此有关。

最佳答案

拥有 INLINABLE 的一个直接好处(或 INLINE )本地 worker 的包装是特化的。 member 的方式在调用站点用固定元素类型定义 Ord可以丢弃字典和适当的compare函数内联或至少作为静态参数传递。

使用直接递归定义,member变成了一个循环中断器并且没有内联,所以调用站点特化没有完成——至少是 INLINABLE 之前的故事。语用。

INLINABLE pragma,调用站点特化确实发生了,字典被淘汰了,但我在几次尝试中没有设法编写一个直接递归的 member这与当前一样有效。但是使用 INLINE pragma,法律仍然有效,没有内联循环断路器;对于 member这意味着没有可能消除字典的调用站点特化。

因此,可能不再需要以这种风格编写函数,但它是为了获得调用站点的特化。

关于optimization - Haskell 平台 : nested functions and optimization,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9757515/

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