R01*_*010 2 javascript performance arguments functional-programming typescript
出于多种原因,我真的很喜欢纯函数方法,但是我的主要音乐会是如果它有相当大的性能损失,特别是在激烈争论的情况下。
例如,代替这个:
// no pure function
import bigState from './somewhere' // imagine a whole state with lots of values.
const impure = () => {
// do something with bigState
}
// pure function
const pure = (bigState) => {
// do something with bigState
}
Run Code Online (Sandbox Code Playgroud)
使用此类函数和参数进行大量工作的应用程序会受到惩罚吗?
如果您想使用纯函数,则必须传入一个无法修改的只读对象。要修改状态,您的纯函数必须返回经过修改的状态副本,而不是更新原始状态。
就传递参数而言,状态的大小并不真正相关。您传入对大状态对象的(小)引用,而不是实际对象本身。无论您的州有多大,参数的大小都是相同的。
如果您有一个非常大的状态,那么使用严格的纯函数将导致每次进行修改时大量复制状态。
为了解决这个问题,您可以考虑使用状态管理工具(例如 immutable.js 或 redux)来为您提供性能优化。
更新
我应该补充一点,纯函数的重要之处不在于它如何从调用环境获取输入,而在于它如何处理该输入。如果一个函数有副作用,那么它就不是纯函数,无论它使用引用参数还是全局变量来导致副作用,都没有关系。
在函数式语言(例如 Haskell)中,编译器将帮助您防止创建不纯的函数。javascript等语言没有直接的函数式编程支持,您必须通过自己编写函数式代码来确保可重复性并避免副作用。
在 javascript/typescript 中帮助强制执行此操作的最简单方法之一是使用不可变状态*。如果您的状态是不可变的,那么您在函数执行期间就更难意外更改它。它还将有助于确保传递参考变量时的可重复结果。如果被引用的对象是不可变的,那么当对同一对象的引用再次传递到函数中时,可以依赖该函数给出一致的结果。
*当然 - javascript 中很少有实际上是只读的。如果开发人员足够努力的话,他们总有办法颠覆你的只读意图。