Control.Lens性能开销

时间:2013-02-13 06:42:34

标签: performance haskell lenses

我很欣赏Control.Lens包。它确实有助于稍微弱的Haskell记录语法。我正在研究图书馆的某些部分,其中表现是一个问题。有没有人知道如果有的话,使用通过类型类暴露的简单镜头(如下所示)与功能中的基本模式匹配相比会有什么性能损失?使用像这样的镜头有可能成为记录命名空间冲突问题的一个很好的工作。我可以自己设置一些基准测试,但是如果有人可以帮我解决问题,我很好奇。感谢。

镜头类

class LensX v where
  _x :: Functor f => (Double -> f Double) -> v -> f v

class LensY v where
  _y :: Functor f => (Double -> f Double) -> v -> f v

class LensZ v where
  _z :: Functor f => (Double -> f Double) -> v -> f v 

镜头实例

instance LensX Vec3 where
  _x f (Vec3 x y z) = fmap (\x' -> Vec3 x' y z) (f x)

instance LensY Vec3 where
  _y f (Vec3 x y z) = fmap (\y' -> Vec3 x y' z) (f y)

instance LensZ Vec3 where
  _z f (Vec3 x y z) = fmap (\z' -> Vec3 x y z') (f z)

提供镜头的模块不必导入Control.Lens包,这很棒。该页面https://github.com/ekmett/lens/描述了该库的使用。

1 个答案:

答案 0 :(得分:7)

这种类型的镜头会给您带来很小的性能损失。它来自所有较高级别的类型,其约束导致字典传递发生。

这是一种极少数情况,当您想要返回data-lens时,它没有那个问题,甚至可以使您的代码更快。数据镜头,如果你解码Store comonad间接,使用了你可以用于镜头的最简单的表示:

newtype Lens s a = Lens (s -> (a, a -> s))

虽然图书馆本身不支持多态镜头,但您可以构建自己的镜头类型,并且仍能为您提供高性能:

newtype Lens s t a b = Lens (s -> (a, b -> t))

出于特定目的,您可能还对linear包感兴趣。