什么带来了更大的性能影响:currying或类型?

Tri*_*Gao 0 haskell

我正在讨论是否应该使用类型类或只是创建具有所有必要功能的部分应用程序.

processWith validate accept reject x xs = if validate x then accept x xs else reject x xs
process = processWith (> 0) (\x xs -> x:xs) (\x _ -> error "Unexpected x: " ++ show x)
Run Code Online (Sandbox Code Playgroud)

据我所知,从概念上讲,这只是个人品味的问题.现在我想知道使用currying而不是类型类的性能影响.

lef*_*out 5

嗯,关键的区别是:对于类型类,您通常会获得更简洁的代码,而显式字典函数则更灵活.

但你不能说两者都更高效.通常,类型类只是作为隐式字典参数实现,所以基本上是第二种方法的语法糖.在性能关键的情况下,GHC通常应该能够内联任何额外的呼叫,然后根本不能真正作为"性能损失".关于类型类的好处是你可以使用{-# SPECIALISE instance #-}编译指示以非常简单的方式帮助这种内联; 使用明确传递的字典使用{-# INLINABLE #-}往往更加繁琐.但是,再次明确更通用,因此您可能会发现使用先验不可预测组合优化特定呼叫更容易.

结论:最好的办法可能是两个版本,一个带字典参数的版本和类型类方法.这也适用于许多标准库例程.

  • 我相信@leftroundabout正在讨论"By"函数及其相应的类型类.见http://hackage.haskell.org/package/base-4.6.0.1/docs/Data-List.html#v:nub和http://hackage.haskell.org/package/base-4.6.0.1/docs /Data-List.html#v:nubBy (2认同)