我试图查看for和reduce在数值数组之间的性能差异,并且我可以看到总是我正在测量的第二个函数(无论是for还是reduce)更快比第一。我猜想这与使用节点的数据缓存或线程池大小有关。这是代码:
process.env.UV_THREADPOOL_SIZE = 1;
let array = [
1,
23,
4,
5,
6,
7,
8,
7,
65,
4,
3,
23,
43,
2,
23,
32,
23,
23,
234,
243,
423,
432,
43,
23,
2,
23,
2,
23,
];
let sum = 0;
console.time('reduce');
sum = array.reduce((s, p) => (s += p), 0);
console.timeEnd('reduce');
sum = 0;
console.time('for');
for (let i = 0; i < array.length; i++) {
sum += array[i];
}
console.timeEnd('for');
此代码显示了不同的结果:
process.env.UV_THREADPOOL_SIZE = 1;
let array = [
1,
23,
4,
5,
6,
7,
8,
7,
65,
4,
3,
23,
43,
2,
23,
32,
23,
23,
234,
243,
423,
432,
43,
23,
2,
23,
2,
23,
];
let sum = 0;
console.time('for');
for (let i = 0; i < array.length; i++) {
sum += array[i];
}
console.timeEnd('for');
sum = 0;
console.time('reduce');
sum = array.reduce((s, p) => (s += p), 0);
console.timeEnd('reduce');
我的意思是,如果您颠倒执行顺序,则测量结果将有所不同。
要进行测试,我正在使用节点v11.11.0
有什么想法吗?
编辑:我不是在寻找解释为什么为什么reduce快于for或类似的东西。我想知道为什么nodejs在这种操作序列中产生这种结果。
答案 0 :(得分:2)
我的意思是,如果您颠倒执行顺序,则测量结果将有所不同。
这意味着:您的测试存在某种缺陷,或者结果是如此随机,以致您无法基于它们做出判断。
更频繁地运行测试(几千次),然后花费平均时间(通过该时间来平均化其他代码段的影响(您正在多线程计算机上运行),然后迫使引擎选择它最强大的优化)。
在此之前,无法判断其中之一是否更快。结果很可能是:没关系,两者都足够快。
答案 1 :(得分:1)
经过测试,两者之间没有很大的时间差。
在链接中,您可以通过修改执行次数对其进行测试。
https://repl.it/@statefull/TrustworthyDefiniteArraylist
经过一些测试,问题出在console.time
函数上。
看到这个:
https://repl.it/@statefull/WrathfulCostlyIrc
第一次调用console.time
会花费更多时间。每次执行时都会将其与Date.now
进行比较。
更多测试表明,直到第一个console.timeEnd
的时间测量才是真实的。
答案 2 :(得分:0)
您为reduce的每次迭代将一个函数添加到堆栈中(() => {}
是一个新的函数调用)。这些函数调用会增加整个过程的额外时间。
只要时间限制不是很严格或数组很大,提高可读性通常是值得的。
答案 3 :(得分:0)
这是脚本或JIT编译语言中的常见现象,与编译器的开销减慢了操作速度有关,但这只是第一次。第一次之后,您将调用已编译的代码,而不是编译脚本,尽管这取决于执行引擎的实现方式。这就是为什么测试通常要求您一次执行一次而不是几次(数千次,理想情况下)的原因
答案 4 :(得分:-2)
Map / Reduce / Filter / Find很慢,因为它们具有回调函数,这些函数会增加开销