在相同的空间和时间复杂度类别中,是否每个命令式算法都有一个纯函数等价物



根据我的个人经验,我想答案是否定的。以可变数组为例。似乎有一些问题可以通过使用具有随机访问的可变数据结构(即数组(来最有效地解决。你可以使用一个不同的数据结构,比如字典(F#中的映射(,它与函数方法兼容,但相比之下,你不会有随机访问,你的算法的效率会比因子logn更差。在一些非常罕见的情况下,使用别名不仅方便,而且更高效,因为它能够以不同的方式访问相同的数据结构。但混叠也与函数方法的不变性不兼容。

像这样的例子表明,纯函数方法不可能在所有情况下都像命令方法那样有效。当然,我知道函数语言是图灵完备的,但如果它也告诉我们一些关于时间和空间复杂性的东西,我对这个证明的记忆还不够好,无法判断。那么,从理论角度来看,我们对此了解多少呢?我的假设正确吗?

简短的回答是肯定的。功能数据结构效果较差:

  • MapSet是树,依赖于比较,而不是散列码。因此log(n)
  • List确实为您提供了和可变数组相同的API,但它是一个链表。因此CCD_ 5用于随机接入

然而,这是一个已知的不变性的折衷方案-在不可变链表中"替换"1个元素更便宜,因为你只需要更新1个元素并重用其余元素,而如果你想要一个不可变数组,你必须完全复制它。

所以FP更多的是稳定的代码、可预测的行为和高开发速度。然而,就性能而言,系统的大多数部分并不是关键的,所以您不会真正注意到两者之间的资源消耗差异,而关键部分肯定可以优化为使用可变结构。

既然您标记了它,F#是一种很好的语言,因为它对FP和OOP都有很好的支持。

Pippenger显示

  1. 与在n步骤中操作的纯程序相比,不纯程序最多有log(n(乘法开销(在Big-O意义上(
  2. 确实存在某些问题,对于这些问题,log(n(因子实际上是必要的

然而,存在一些感兴趣的问题,其中log(n(因子是不必要的,并且还要记住,在现实世界的用例中,常量因子也可能很重要。

最新更新