我在 react 应用程序中有一段相当时间紧迫的代码,该代码在表单中的所有用户击键上运行。它通常没有性能问题,但我正在考虑对其进行优化,并对for (let k in obj)
和Object.keys(obj).reduce
之间的性能差异感到有些惊讶。
我认为在 JS 中设置函数调用堆栈等会很昂贵,但是以下例程的功能版本将程序化了(整整一个数量级!
以下是不同的版本:
程序
const generateProps = (fields, source, start) => {
if (!fields) return start
let finish = {...start}
for (let k of Object.keys(fields)) {
const fld = fields[k]
if (fld instanceof Array) {
if (fld.length === 0) continue
// Handle an array of scalars (e.g. phoneNumbers)
if (fld[0].hasOwnProperty('value')) {
let sf = {}
for (let i = 0; i < fld.length; i++) {
sf[i] = fld[i]
}
finish = generateProps(sf, source[k], finish)
// Handle an array of fields (e.g. addresses)
} else {
for (let i = 0; i < fld.length; i++) {
finish = generateProps(fld[i], source[k][i], finish)
}
}
} else {
finish = {
hasError: fields[k].hasError || fields[k].value === '' || finish.hasError,
isEditing: fields[k].editing || finish.isEditing,
unchanged: (!fields[k].isNew && fields[k].value === source[k]) && finish.unchanged,
hasNew: fields[k].isNew || finish.hasNew
}
}
}
return finish
}
功能的
const generateProps = (fields, source, start) => {
if (!fields) return start
const keys = Object.keys(fields)
return keys.reduce((props, k) => {
const fld = fields[k]
if (fld instanceof Array) {
if (fld.length === 0) return props
// Handle an array of scalars (e.g. phoneNumbers)
if (fld[0].hasOwnProperty('value')) return generateProps(fld.reduce((sf, f, i) => {sf[i] = f; return sf}, {}), source[k], props)
// Handle an array of fields (e.g. addresses)
return fld.reduce((subp, f, i) => generateProps(f, source[k][i], subp), props)
}
return {
hasError: fields[k].hasError || fields[k].value === '' || props.hasError,
isEditing: fields[k].editing || props.isEditing,
unchanged: (!fields[k].isNew && fields[k].value === source[k]) && props.unchanged,
hasNew: fields[k].isNew || props.hasNew
}
}, start)
}
这是jperf结果
正如您在运行测试时所看到的,过程版本比功能版本慢近 50%。我很想听听为什么会有如此明显的差异的细分。
好的,我发现了一个关键的区别!功能版本正在start
变异(我假设reduce会创建一个副本,来自ramdajs
背景),而程序是创建一个副本。如果我将前 reduce
调用的最后一个参数更改为 {...start}
,它们大约是偶数。
这让我很纳闷...为什么物体传播这么慢?