繁体   English   中英

功能编程效率与命令式

[英]functional programming efficiency vs imperative

我是函数式编程的新手,我只是遇到了一些问题,并且想知道是否有办法解决这个问题。

假设我有

myArray = [
  { a : 1 }
  { a : 4 }
  { a : 5 }
  { a : 6 }
  { a : 7 }
  { a : 8 }
]

假设我需要对此数据集进行统计操作,例如

const median = myArray[ Math.ceil( myArray.length / 2 ) ]['a'] // Math.ceil .. Side Effect?
const fiveOrMore = myArray.filter( value => value.a >= 5 )
const lessThanFive = myArray.filter( value => value.a < 5 )

一些随意的例子。 目前的问题是,随着我需要做的统计操作量的增加,效率会降低。

凭借命令式的风格,我可以在ONE for循环中做所有事情。 这是我正在采用的函数式编程的错误方法还是功能编程范式本身的折衷

功能风格你也可以在一个减少中完成它。 只需要一个检查元素在下面的函数,累加器就是一个带有两个列表的结构,你要添加元素。

如果您正在考虑通过一系列高阶函数传递列表,那么您可以减少Trancducers的开销,这基本上像个别map一样工作, filter但操作之间没有列表。

如果您可能不会使用结果中的所有元素,则会有使用延迟评估的

还有发电机 基本上,你可以多次for循环和使用ỳield来“回报”的值,你可以链接这些,因为所有发电机可以用迭代for of 此外,只要有足够的数据,您就可以暂停。

所以这些都有利有弊。 如果你要使用生成器和流来计算所有元素将会有一点性能。 传感器可能是一个更好的选择,它可以提供很少的列表制作的可组合性,但循环当然会更快。

通过功能实现,测试更容易,您可以测试隔离的各个阶段。 规则整个应用程序的一个非常大的循环通常很难调试。 当你有一个只在功能样式中重写一个循环的reduce时,这也会发生。

这当然不那么高效。 而性能的提升取决于您选择的风格。

有人可能认为这不是什么大问题,因为时间复杂度是O(n)唯一的区别是常数 我会说确保你对应用程序进行性能测试。 如果它很慢 - 是时候优化某些代码块了。

过早优化是邪恶的。 在许多情况下,命令式代码比功能性代码更快或更快地运行得快得多,并且根据情况你可能会或可能不会那么好。

此外,还有各种技术可以改善性能。 你不一定要改变风格。 比方说,在某些情况下, memoization可以大大提高函数的速度,同时保持代码的功能。 只是在盒子外思考。

你可以用功能或命令式的方式将事物塞进一个循环中。 这两种风格中都会损害可读性。 这两种样式中,编译器都可以进行循环融合以消除额外的循环。 此外,单个循环并不总是更快,编译器将能够辨别融合比人类更容易融合的情况。

正如Sylwester指出的那样,函数式编程有许多技术可以让你分别编写循环但是一起执行它们。 功能样式也更容易显式并行化到多个线程上。

通常还有库函数已经在单个循环中执行了您想要的操作,并且更具描述性和更简洁。 例如,您的最后两行可以使用分区完成:

_.partition(myArray, x => x['a'] < 5)

我的一个口号是:

“我不在乎我能以多快的速度计算出错误的答案。”

我可能会尝试编写一些超快速代码,但如果我的代码很难理解并因此很容易引入错误/很难发现错误,那么它就有风险。 除非代码对执行速度至关重要,否则我选择的方法最容易表达我正在尝试做的事情:有时功能方法可以使您的意图非常清晰,而在其他情况下,命令更合适。

一旦我有了可行的代码,并通过了一组单元测试,我就可以根据需要重写以寻求更快的速度。

顺便说一下,这就是我现在享受Swift的原因 - 我有功能和必要的选择。 哦,我知道它不是纯粹的功能,但是用我的工程而不是计算机科学的帽子,它足够接近! ;-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM