1)我们知道,map()和reduce()没有副作用。如今,我们手机上也有多核心。那么使用它们会更有效吗?
2)另一方面,在大多数浏览器上只有1个js执行线程。为服务器端脚本编写了map()和reduce()吗?
答案 0 :(得分:7)
我今天刚刚测试了这个,使用map和reduce over floating point number,使用最新的node.js版本,答案是map和reduce比常规for循环慢两个数量级。
var r = array.map(x => x*x).reduce( (total,num) => total+num,0);
〜11,000ms
var r = 0.0;
array.forEach( (x,i,a) => r += x*x )
〜300ms的
var r = 0.0;
for (var j = 0; j < array.length;j++){
var x = array[j];
r += x*x;
}
〜35MS
编辑:人们应该注意到这种差异在Firefox中要小得多,而且在未来的Node / Chrome版本中也可能会少得多。
答案 1 :(得分:3)
1)
map()和reduce()
没有副作用
好。你很好地可以实现map并减少有副作用的回调。没有什么可以阻止它,并且在当前的JavaScript状态下它甚至都不被认为是不好的做法。
<强> 2)强>
在大多数浏览器上只有1个js执行线程
今天所有的JS引擎中只有一个线程,即使它们在服务器端运行(实际上可以有更多但孤立的,不访问同一个阵列)。
因此没有副作用的事实不会使数组修改可以并行化。除了在标准数组上顺序调用回调之外,没有JS引擎可以做到。
注意:正如zirak所指出的那样,这不是标准的Mozilla ParallelArray,可能有助于并行执行。我不知道V8上是否有类似内容。
答案 2 :(得分:0)
很容易被忽视,但获得MapReduce优势的关键是
A)利用优化后的随机播放。通常,您的map和reduce函数可以用慢速语言实现,只要shuffle(最昂贵的操作)得到很好的优化,它仍然可以快速和可扩展。
B)利用检查点功能从节点故障中恢复(但希望你的CPU核心不会失败)。
所以最后,map-reduce实际上既不是map,也不是reduce函数。它围绕着它的框架;即使是糟糕的地图也会给你带来良好的表现&#34;并且&#34;减少&#34;函数(除非您在随机播放步骤中失去对数据集大小的控制!)。
通过在单个节点上执行多线程map-reduce获得的收益相当低,并且很可能有更好的方法来并行化商店以实现共享内存架构而不是map-reduce 强> ...
不幸的是,这些天围绕mapreduce有很多炒作(而且理解力太少)。如果您查找original paper,它会详细介绍&#34;备份任务&#34;,&#34;机器故障&#34;和&#34;地点优化&#34; (对于内存中的单主机用例,这两者都没有意义。)
因为它有一张&#34;地图&#34;和&#34;减少&#34;并没有使它成为&#34; mapreduce&#34;然而,
如果它具有优化的随机播放,节点崩溃和落后者恢复,那么它只是一个MapReduce。
答案 3 :(得分:0)
只要阵列的尺寸非常低(按10的顺序),那么性能就没有太大差别,但是当阵列的大小增加到非常大的值时,则使用传统的for循环是一个伟大而好的方法,因为我们只需要遍历元素并在我们指向的特定索引处获取值,但在其他方法中,不仅我们在索引处获取值,而且还有其他信息,如索引,(在map,reduce,forEach中)和累加器值(在reduce中)。而这些方法需要一个回调函数,它们都会占用内存上的大量存量以进行回调,这进一步降低了性能速度。
您可以使用以下脚本检查其理由。 只需查看控制台记录的值即可。
var scripts=[];
// GLOBAL variales declaration
var a=[];
function preload() {
for(var i=0;i<100000;i++) a[i]=i;
}
preload();
// TEST function 0
scripts.push(function() {
var sum=0;
a.forEach(function(v) {
sum+=v;
});
//console.log(sum);
});
// TEST function 1
scripts.push(function() {
a.reduce(function(acc,v) {
return acc+v;
});
});
// TEST function 2
scripts.push(function() {
var sum=0;
for(var i=0;i<a.length;i++) {
sum+=a[i];
}
});
// EVALUATION
scripts.forEach(function(f,index) {
var date=new Date();
for(var i=0;i<10000;i++) {
f();
}
console.log("call "+index+" "+(new Date()-date));
});