纯函数式编程的效率

有谁知道纯功能编程而不是强制性编程(即容许反作用)发生时,最糟糕的渐近减速多是什么? html

从itowlson的评论中澄清 :是否存在最知名的非破坏性算法比最知名的破坏性算法渐近恶化的问题? 算法


#1楼

本文声称, 联合查找算法的已知纯功能实现都比它们发布的算法具备更差的渐进复杂度,后者具备纯功能接口,但内部使用可变数据。 编程

其余答案声称永远没有任何区别,例如,纯功能代码的惟一“缺点”是它能够并行化,这一事实使您对功能编程社区在这些问题上的了解程度/客观性有所了解。 数组

编辑: 数据结构

下面的评论指出,对纯函数式编程的优缺点的偏颇的讨论可能不会来自“函数式编程社区”。 好点子。 也许我看到的倡导者只是在评论中说是“文盲”。 编程语言

例如,我认为该博客文章是由能够说是功能编程社区表明的人撰写的,而且因为它是“懒惰评估的要点”列表,所以,它是说起任何缺点的好地方懒惰和纯函数式编程可能具备。 解雇如下人员是一个不错的选择(从技术上讲是正确的,但偏向于不搞笑): 分布式

若是严格函数在严格语言中具备O(f(n))复杂度,那么在懒惰语言中函数也具备O(f(n))复杂性。 为何要担忧? :) 函数式编程


#2楼

我建议阅读Haskell的性能 ,而后看一下功能语言与程序/ OO语言的基准游戏性能。 函数


#3楼

根据Pippenger [1996]的研究 ,当将纯功能的Lisp系统(具备严格的评估语义,而不是惰性的)与能够变异数据的Lisp系统进行比较时,能够翻译为在O( n )中运行的不纯Lisp编写的算法。转换为纯Lisp中运行时间为O( n log n )的算法(基于Ben-Amram和Galil [1992]关于仅使用指针模拟随机存取存储器的工做)。 皮蓬格(Pippenger)还肯定,有些算法是您能够作的最好的。 在不纯系统中存在O( n )在纯系统中存在Ω( n log n )的问题。 性能

关于本文有一些警告。 最重要的是,它不解决惰性函数语言,例如Haskell。 Bird,Jones和De Moor [1997]证实由Pippenger构造的问题能够在O( n )时间内以一种惰性函数语言解决,但它们并无肯定(据我所知,没有人知道)是否没有一种惰性函数语言能够像变种语言同样在相同的渐近运行时间内解决全部问题。

由皮蓬格(Pippenger)构造的问题须要专门构造Ω( n log n )才能得到此结果,而且不必定表明实际的实际问题。 对这个问题有一些限制,这是出乎意料的,可是对于证实工做是必不可少的。 特别地,该问题要求结果是在线计算的,而没法访问未来的输入,而且输入由来自无限可能原子集合的原子序列组成,而不是固定大小的集合。 而且本文仅针对线性运行时间的不纯算法创建(下界)结果。 对于须要更长运行时间的问题,可能会在运行时间更长的算法所需的额外操做过程当中,“吸取”线性问题中出现的额外O(log n )因子。 Ben-Amram [1996]简要地探讨了这些澄清和开放性问题。

实际上,能够用纯功能语言以与具备可变数据结构的语言相同的效率来实现许多算法。 有关有效用于实现纯功能数据结构的技术的良好参考,请参见Chris Okasaki的“纯功能数据结构” [Okasaki 1998] (这是其论文的扩展版本[Okasaki 1996] )。

任何须要在纯功能数据结构上实现算法的人都应该阅读Okasaki。 经过使用平衡的二叉树模拟可变内存,您每次操做老是最糟糕的状况是O(log n )变慢,可是在许多状况下,您能够作得更好,并且Okasaki描述了许多有用的技术,从摊销技术到实物化,逐步进行摊销的时间。 纯功能数据结构可能很难使用和分析,可是它们提供了不少好处,例如引用透明性,有助于编译器优化,并行和分布式计算以及实现诸如版本控制,撤消和回滚之类的功能。

还要注意,全部这些仅讨论渐近运行时间。 许多实现纯功能数据结构的技术会给您必定程度的恒定因子减慢,这是因为它们须要额外的簿记功能以及相关语言的实现细节。 纯功能数据结构的好处可能赛过这些恒定因素的减速,所以您一般须要根据所讨论的问题进行权衡。

参考文献


#4楼

在固定的内存使用上限上,应该没有区别。

证实草图:给定固定的内存使用上限,一我的应该可以编写一台虚拟机,该虚拟机以与您实际在该计算机上执行相同的渐进复杂度执行命令式指令集。 之因此这样,是由于您能够将可变内存做为持久性数据结构进行管理,从而实现O(log(n))的读写,可是因为内存使用量具备固定的上限,所以您能够拥有固定的内存量,从而致使这些衰减到O(1)。 所以,功能实现能够是在VM的功能实现中运行的命令式版本,所以它们都应具备相同的渐近复杂度。


#5楼

确实有几种算法和数据结构,即便是惰性的,也没有已知的渐近有效的纯函数解(在纯lambda演算中能够实现)。

  • 前述工会发现
  • 哈希表
  • 数组
  • 一些图算法
  • ...

可是,咱们假设在“命令式”语言中,对内存的访问为O(1),而在理论上不可能如此渐近(即对于无限制的问题大小),而且对庞大数据集中的内存的访问始终为O(log n) ,可使用功能语言进行仿真。

一样,咱们必须记住,实际上全部现代功能语言都提供可变数据,Haskell甚至在不牺牲纯度的状况下提供了数据(ST monad)。

相关文章
相关标签/搜索