3个版本

0.1.2 2019年10月2日
0.1.1 2019年10月1日
0.1.0 2019年9月30日

#1028 in 数据结构

MIT 许可证

15KB
243

Myopic

我的光学库Myopic,可能是功能镜头概念的糟糕实现。这是一个美妙的概念,如果你想要一个优雅的实现,请参阅Haskell生态系统中的lens,以及许多优秀的介绍之一,如lens over tea

Myopic并不优雅——它满足了我对在可变数据上操作镜头的需求,这种需求没有或只有很少的性能损失,并且足够简单,可以在我的其他库中使用。

概念

这个库包含三种镜头概念的实现。它们都是最简单的镜头类型,只能获取和设置结构中的数据(不是那些可以做更多事情的复杂的Haskell镜头)。

镜头以结构体实现,其中包含闭包(lens)、boxed trait对象(lens_box)或函数指针(lens_fn)。

每个镜头实现都有一个Lens类型,其中包含获取和设置数据的函数,以及一个ComposedLens类型,用于嵌套组合镜头和ComposedLens。这种实现来自lenses库(应得的赞誉)。

之所以有三种实现,是为了进行基准测试,如下所述。结论是,'lens'模块在最坏的情况下也快得多,在最好的情况下则快得多。

基准测试

可以使用cargo bench运行基准测试

cargo bench

它们表明,'lens'模块无疑是最快的。它似乎可以内联,以至于我不得不在criterion中使用black_box才能从中获取任何基准测试数据。

其他实现似乎承担了一些间接的惩罚,这些惩罚不能内联(我假设)。这看起来随着组合的增多而恶化,而'lens'模块中的组合则不会产生明显的惩罚。

名称

名称中的笑话是,这既是我的光学库,也可能是一个糟糕的光学库。Myopic意味着视力不好,听起来像“我的光学”。希望这有点好笑。

比较

有几个Rust镜头库,其中一些相当广泛,一些则具有截然不同的设计。

  • lenses 非常简单,是我开始使用的库,这也最终导致了 Myopic 的诞生。这个库使用了一个 Lens 特征,一个用于 Lens 类型的实现,另一个用于包含组合镜头的类型。这就是我在 Myopic 中最终使用的设计,基于我在 lenses 中找到的内容。我没有对这个进行基准测试,但 lenses 可能和 Myopic 一样快。我在处理一个特定用例时遇到了困难,即我希望能够修改可能没有地址的数据,并想要修改现有数据。也许 lenses 可以做到这一点,但我不知道该怎么做。
  • photonix 非常有趣——它使用完全不同的实现方式,仅使用特征,并且不需要在内存中保留闭包。它似乎允许深入到嵌套结构中,并构建对这些结构的访问(据我所知,使用宏)。很酷。
  • refraction 非常广泛,将涉及的概念分解成许多小部分,并逐步构建。它包含像 Prisms 这样的额外概念,并且总体上比 Myopic 更好地构建。考虑到涉及到的特征数量,它似乎对我来说有点混乱,尽管我认为任何 Rust 中的镜头实现都将需要这些。
  • shoggoth 也很酷,看起来很全面。根据其名称(自我承认)它相当复杂。我想要一个简单易懂的东西,所以我没有选择走这条疯狂的路。
  • fp-core 只有一个镜头特征,并且我不认为它支持我在原地修改数据的用例。
  • rustz 的实现比 Myopic 更好,它采取了稍微不同的设置方法。我相信它排除了我在原地更新数据,但如果这最终证明并不重要,那么 rustz 可能是最佳选择,因为它相似,而且实现不如某些实现那么不透明。

许可证

Myopic 根据您的偏好,采用 MIT 或 Apache2 许可证。

无运行时依赖