gpt4 book ai didi

javascript - Javascript 中嵌套 for 循环与数组函数的性能

转载 作者:搜寻专家 更新时间:2023-10-31 23:27:19 24 4
gpt4 key购买 nike

我昨天写了一小段代码,它使用两个 for 循环来比较两个数组中的对象(尽管数组是相同的)。

var result = []
for (var i = 0; i < res.length; i++) {
var tempObj = {}
tempObj.baseName = res[i].name
tempObj.cnt = res[i].cnt
tempObj.matches = []
for (var j = 0; j < compareArr.length; j++) {
if(natural.LevenshteinDistance(res[i].name, compareArr[j].name) === options.distance) {
tempObj.matches.push(compareArr[j])
}
}
if (tempObj.matches.length > 0) {
result.push(tempObj)
}
}

然而,过去几个月我一直在进行函数式编程,并决定使用更函数式的方法重写代码块,结果如下:

var result = res.
map(function(baseItem) {
baseItem.matches = compareArr.
reduce(function(acc, compItem) {
if(natural.LevenshteinDistance(baseItem.name, compItem.name) === options.distance) {
acc.push(compItem)
}
return acc
}, [])
return baseItem
}).
filter(function(item) {
return item.matches.length > 0
})

我的路线感觉它的响应有点慢,但是,正在迭代的数据是数据库查询的结果,可能包含成千上万的项目,我想确保我不会损害性能服务器无缘无故。所以,我将函数插入 jsperf,然后 the results令人难过。 for 循环以大约 2,600 次操作/秒的速度运行,而第二个 block 以大约 500 次操作/秒的速度运行。 :(

问题是,我的第二个block写的不好吗,能改进一下吗?如果不是,这正常吗?我看到越来越多的人在插入函数式风格的 javascript。

我是否以风格的名义损害了性能?我是否应该享受学习函数式语言的乐趣,而将其从我的 javascript 中剔除?

http://jhusain.github.io/learnrx/

https://github.com/timoxley/functional-javascript-workshop

https://medium.com/javascript-scene/the-two-pillars-of-javascript-ee6f3281e7f3

John Resig 似乎是他的粉丝 -> http://ejohn.org/blog/partial-functions-in-javascript/

http://shop.oreilly.com/product/0636920028857.do

我意识到这篇文章很快就从非常具体变成了非常笼统,如果有建议,我会编辑范围并发布新文章。

编辑:为组添加了 lodash 和下划线测试。 Lodash 以大约 870 次操作/秒的速度位居第二,下划线仅以 475 次操作/秒。测试 here .

我找到了 fast.js 与 for 循环和 js native 函数的基准测试 here它同样被一个简单的 for 循环所震撼。

最佳答案

数组方法本质上比 for 循环慢,因为 1) 它们必须在每次迭代时重新构建函数作用域,以及 2) 其中一些方法(.map.reduce) 必须重建数组的副本(因此需要更多的内存、更多的 GarbageCollection 和通常更多的操作)。因此,如果您担心速度,请保持尽可能低的速度。

不过,对于您的算法,您可以采取一些措施来改进运行时间。您最昂贵的操作是 LevenshteinDistance,因此对其进行优化会给您带来相当大的速度提升。

您可以做的最简单的事情是对字符串进行长度检查并提前返回:您知道如果 2 个字符串的长度相差超过 options.distance,它们的 Levenshtein 距离将为至少不止于此,这样您就可以轻松早日返回:

for (var j = 0; j < compareArr.length; j++) {
// This check was added
if (Math.abs(res[i].name.length - compareArr[j].name.length) > options.distance) {
continue;
}
if(natural.LevenshteinDistance(res[i].name, compareArr[j].name) === options.distance) {
tempObj.matches.push(compareArr[j])
}
}

该方法本身也有一些改进,在另一篇 stackoverflow 帖子中有更好的解释:https://stackoverflow.com/a/3183199/574576

关于javascript - Javascript 中嵌套 for 循环与数组函数的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26811628/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com