Control.Lens性能开销

MFl*_*mer 7 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 
Run Code Online (Sandbox Code Playgroud)

镜头实例

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)
Run Code Online (Sandbox Code Playgroud)

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

ert*_*tes 7

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

这是一种罕见的情况,当你想要回到数据镜头时,它没有那个问题,甚至可以让你的代码更快.数据镜头,如果你解码Storecomonad间接,使用你可以用于镜头的最简单的表示:

newtype Lens s a = Lens (s -> (a, a -> s))
Run Code Online (Sandbox Code Playgroud)

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

newtype Lens s t a b = Lens (s -> (a, b -> t))
Run Code Online (Sandbox Code Playgroud)

出于特定目的,您可能也对线性包装感兴趣.