Ana / Catamorphisms只是慢一点吗?

时间:2014-05-14 20:09:58

标签: haskell kdtree catamorphism recursion-schemes

写完this article之后,我决定把钱放在嘴边,并开始将我以前的项目转换为使用recursion-schemes

有问题的数据结构是lazy kdtree。请查看explicitimplicit递归的实现。

这主要是一种简单的转换:

data KDTree v a = Node a (Node v a) (Node v a) | Leaf v a

data KDTreeF v a f = NodeF a f f | Leaf v a

现在,在对整个shebang进行基准测试后,我发现KDTreeF版本比普通版本(find the whole run here)的慢两倍

只是额外的Fix封装器让我放慢了速度吗?我有什么可以做的吗?

注意事项:

  • 目前专门针对(V3 Double)。
  • 这是在变形应用之后的cata-。 Hylomorphism不适合kdtrees。
  • 我多次使用cata (fmap foo algebra)。这是好习惯吗?
  • 我使用Edwards recursion-schemes包。

编辑1:

这有关系吗? https://ghc.haskell.org/trac/ghc/wiki/NewtypeWrappers newtype Fix f = Fix (f (Fix f))不是"免费"?

编辑2:

刚做了另一堆基准测试。这次我测试了树木的构造和解构。基准测试:https://dl.dropboxusercontent.com/u/2359191/2014-05-15-kdtree-bench-03.html

虽然Core输出表明中间数据结构没有完全删除,现在线性搜索占主导地位并不奇怪,KDTreeF现在比KDTree略快。然而,并不重要。

2 个答案:

答案 0 :(得分:17)

我刚刚实现了树的Thing + ThingF + Base instance变体。猜猜看......这个速度非常快。

我的印象是这一个是所有变种中最慢的。我真的应该阅读我自己的帖子......我写的行:

  

没有找到TreeF结构的痕迹

让数字说明一切,kdtreeu是新变种。结果并不总是像这些情况一样清晰,但在大多数情况下,它们至少与显式递归一样快(基准中为kdtree)。

Benchmark results

答案 1 :(得分:1)

我没有使用递归方案,而是我自己的"手工推出" cata,ana,Fix / unFix用小语言生成(列表)和评估程序,希望找到一个与(输入,输出)对列表相匹配的程序。

根据我的经验,cata优化比直接递归更好,并提高了速度。此外,IME,ana防止了我的天真生成器导致的堆栈溢出错误,但是这种错误集中在最终列表的生成周围。

所以,我的答案是不,他们并不总是慢,但我没有看到任何明显的问题;所以他们可能只是在你的情况下慢。递归方案本身也可能没有针对速度进行优化。