performance - 部分评估右手操作符部分

标签 performance haskell ghc

我有一个函数(*~) .评估 x *~ y 的大部分成本来自检查第二个参数,大致如下:

(*~) :: a -> b d -> c d a
x *~ y = case y' of
           Bar -> cheapFunction y' x
           Baz -> cheapFunction2 y' x
           Quux -> cheapFunction3 y' x
  where
    y' = expensive y

有什么方法可以说服 GHC 部分评估运算符部分,如 (*~ y) ?

我试着像这样重写它:
(*~) = flip go
  where
    go y = let y' = expensive y
            in case y' of
                 Bar -> cheapFunction y'
                 Baz -> cheapFunction2 y'
                 Quux -> cheapFunction3 y'

但这似乎没有帮助。我想这可能是因为 flip在翻转之前需要它的所有论点?

一种方法是翻转运算符本身,但当昂贵的操作数位于右侧时,它会更自然地读取,因为它与现有的符号对齐。

可以一个精心制作的{-# RULE #-}保释我在这里?如果是这样,它应该说什么? (我不清楚在规则查找匹配之前,分割语法将被脱糖多远,等等。)

最佳答案

要触发这样的优化,您需要确保您的函数被内联。放置{-# INLINE (*~) #-}声明 (*~) 之前的 pragma功能。我不能保证它会解决你的问题,但这是我看到它被接近的唯一方式。我会使用 "ghc-core" 之类的工具检查生成的核心代码。之后确定。

但是,您的问题实际上只是代码组合不当的迹象。您的功能正在做多个不相关的事情。 expensive y应该简单地排除它,那么您的问题将被删除。即,使用模式应该是 x *~ expensive y而不是 x *~ y .

关于performance - 部分评估右手操作符部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33268177/

相关文章:

haskell - 多变量函数的导数和对应的带有向量空间包的雅可比行列式

list - 在 Haskell 中将元素插入列表中给定的索引

windows - 如何在 Windows 上将 GHCi 提示符设置为 lambda 字符?

haskell - 是否可以在 cabal 项目中编译 "only a file"?

OpenGL 4.1 和 3.1+,主要区别是什么?

performance - 我可以为此使用比树更快的数据结构吗?

haskell - 严格评价的妙用在哪里?

Haskell GHC 动态编译仅适用于第一次编译

c++ - 使用相同的 golang 片段查询 mysql 数据库的巨大性能差异

html - 选定的链接需要突出显示