使用镜头有什么优点和缺点

使用镜头有什么优点和缺点

本文介绍了使用镜头有什么优点和缺点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎没有任何缺点,同时比标准的Haskell有明显的优势:有没有我不应该在任何可能的情况下使用镜片?是否有性能方面的考虑?另外,模板Haskell是否有明显的开销?

解决方案

透镜构成了使用数据构造函数的直接闭包的替代方法。因此镜头与使用函数和数据构造函数直接相同的警告。



一些缺点是因为这个原因:

每当您修改镜头时,您可能会导致(重新)创建大量对象。例如,如果你有这样的数据结构:

  A {B {C {bla =foo}}} 

...以及类型 Lens A String ,你将创建一个新的 A B C 每次你修改该镜头。这在Haskell中并不罕见(创建大量对象),但创建对象隐藏在镜头后面,难以发现潜在的性能下降。


  • A由于使用了映射功能,镜头也可能造成效率低下。例如,如果您制作的镜头可以修改列表中的第26个元素,则由于查找时间的原因,它可能会导致很多放缓。



  • 以及优点:$ b​​
    $ b


    • 透镜与普通记录结合可以很好地用于(参见函数,以及在Snap Web框架中使用 withSomething 函数的类似模式。

    • 镜头显然实际上并没有实际修改任何内存,所以当您需要在并发上下文中推理状态时,镜头非常有用。因此,镜片在处理各种图形时非常有用。然而,透镜并不总是与数据构造器上的闭合同构。以下是一些差异(采用作为这里的实现):


      • 大多数透镜实现使用某种形式的数据类型来将访问器和增变器作为一对。对于 data-lens ,这是。这意味着每次创建镜头时,由于正在创建数据结构,因此会产生非常小的额外开销。

      • 因为镜头依赖于某些未知映射的值,所以它可能会变得更难理解垃圾收集,并且你可能会(逻辑)内存泄漏,因为你忘记了你正在使用一个非常通用的镜头,这取决于一大块内存。举个例子,一个镜头访问某个大型矢量中的一个元素,该镜头由另一个隐藏第一个镜头的镜头组成,这使得难以看出组合镜头依然依赖于大量内存。
      • >


      模板Haskell代码在编译时运行,不会影响透镜的运行时性能。


      Lenses don't seem to have any disadvantages while having significant advantages over standard Haskell: Is there any reason I shouldn't use lenses wherever possible? Are there performance considerations? Additionally, does template Haskell have any significant overhead?

      解决方案

      Lenses form an alternative to using direct closures over data constructors. Lenses therefore have approximately the same caveats as using functions and data constructors directly.

      Some of the cons because of this:

      • Every time you modify a lens, you might potentially cause a lot of objects to be (re)created. For example, if you have this data structure:

        A { B { C { bla = "foo" } } }
        

        ...and the lens of type Lens A String, you will create a new A, B and C every time you "modify" that lens. This is nothing unusual in Haskell (creating lots of objects), but the object creation is hidden behind the lens, making it hard to spot as a potential performance sink.

      • A lens could also create inefficiencies due to the "mapping function" being used. For example, if you make a lens that modifies the 26 element in a list, it might cause a lot of slowdowns due to the lookup time.

      And the pros:

      • Lenses, in combination with normal records, can be used beautifully with the state monads (see data-lens-fd for an example), and this makes it possible to avoid recreating a lot of objects most of the time, due to extensive data sharing. See for example the focus function, and a similar pattern of using withSomething functions in the Snap Web framework.
      • Lenses obviously don't actually modify any memory in-place, so they are very useful when you need to reason about state in the context of concurrency. Lenses would therefore be very useful when dealing with graphs of various kinds.

      Lenses are not always isomorphic to closures over data constructors, however. Here are some of the differences (taking data-lens as the implementation here):

      • Most lens implementations use some form of data type to store the "accessor" and "mutator" as a pair. For data-lens, it's the Store comonad. This means that every time you create a lens, there'll be a very small extra overhead due to that data structure being created.
      • Because lenses depend on values via some unknown mapping, it might become harder to reason about garbage collection, and you might get (logical) memory leaks because you forgot that you are using a very generic lens that depends on some large chunk of memory. Take, for example, a lens that accesses an element in some large vector, which is composed with another lens that thus hides the first lens, making it difficult to see that the composed lens still depends on the large amount of memory.

      Template Haskell code runs at compile time, and does not affect the runtime performance of lenses whatsoever.

      这篇关于使用镜头有什么优点和缺点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    07-28 06:17