为什么使Vector成为Functor,Monad,Applicative,Alternative,Foldable和Traversable实例的函数变慢?

时间:2011-09-28 12:45:56

标签: performance haskell

vector版本0.8的更改日志列出了以下更改并带有警告:

  

Functor,Monad,Applicative,Alternative,Foldable和Traversable   盒装载体的实例(警告:它们往往很慢而且是   仅提供完整性)

有人可以解释为什么会这样吗?它只是类型类专业化的正常成本,还是更有趣的东西?

更新:查看某些特定情况,例如:

instance Foldable.Foldable Vector where
  {-# INLINE foldr #-}
  foldr = foldr

和其他折叠类似。这是否意味着Vector一般来说折叠很慢?如果不是,是什么让一个非专业的折叠足够慢以保证警告?

2 个答案:

答案 0 :(得分:15)

我在一年半前将这些实例的原始集合提交给了Roman,并且从那时起就维护了vector-instances。 (一旦它们迁移到vector中,我不得不从vector-instances中删除这些实例,现在只为真正奇特的东西维护它)。他担心的是,如果人们使用多态这些实例,那么除非多态函数被内联和单态化,否则使矢量融合的规则不会触发。

它们的存在是因为并非地球上的每一段代码都是特定于矢量的,即使这样,有时也会使用通用名称。

这里的慢是相对的。最糟糕的情况是他们表现得像其他任何人的折叠,绑定等等,但罗曼将每一个盒装价值视为个人侮辱。 :)

答案 1 :(得分:8)

我刚看了一下源代码,实现看起来并不太慢。我认为作者添加了这个警告,因为当你在Vector monad中编写一个程序时,你就是从这样一个高级别的角度来看,很容易忘记每个>>=事实上,它是一个concatMap,往往本来就很慢。

另一件事:Vector对于未装箱的类型来说特别快。因此,用户可能会被吸引使用monad表示法(为了方便起见),而他实际上应该使用未装箱的类型(为了速度)。