最快JavaScript求和
用JavaScript总结数组的最快方法是什么?一个快速搜索翻过来,但我想一个本地解决方案,如果可能的话。这将在SpiderMonkey下运行 在我一直使用的盒子里思考:最快JavaScript求和,javascript,arrays,function,Javascript,Arrays,Function,用JavaScript总结数组的最快方法是什么?一个快速搜索翻过来,但我想一个本地解决方案,如果可能的话。这将在SpiderMonkey下运行 在我一直使用的盒子里思考: var count = 0; for(var i = 0; i < array.length; i++) { count = count + array[i]; } var计数=0; 对于(var i=0;i
var count = 0;
for(var i = 0; i < array.length; i++)
{
count = count + array[i];
}
var计数=0;
对于(var i=0;i
我相信有比直接迭代更好的方法 您应该能够使用
reduce
var sum = array.reduce(function(pv, cv) { return pv + cv; }, 0);
在ES6中引入,它更简单:
sum = array.reduce((pv, cv) => pv + cv, 0);
最快的循环是相反的while循环
var i = arr.length; while (i--) { }
所以,这段代码可能是你能得到的最快的代码
Array.prototype.sum = function () {
var total = 0;
var i = this.length;
while (i--) {
total += this[i];
}
return total;
}
Array.prototype.sum
向数组类添加一个sum方法。。。您可以轻松地将其改为辅助功能。改进
您的循环结构可以更快:
这相当于一个while反向循环。它缓存值并与0进行比较,因此迭代速度更快 有关更完整的比较列表,请参见我的
注意:array.reduce在那里很可怕,但在Firebug控制台中它是最快的
比较结构
我为数组求和启动了一个。它是快速构造的,不能保证完整或准确,但这就是编辑的目的:)对于您的特定情况,只需使用数组的
reduce
方法:
var sumArray = function() {
// Use one adding function rather than create a new one each
// time sumArray is called
function add(a, b) {
return a + b;
}
return function(arr) {
return arr.reduce(add);
};
}();
alert( sumArray([2, 3, 4]) );
基于和
我可以说:
1#最快:用于循环
非决定性方法
然后是
forEach
和reduce
,它们的性能几乎相同,并且在不同的浏览器中有所不同,但它们的性能最差。在搜索对数组求和的最佳方法时,我编写了一个性能测试
在Chrome中,“reduce”似乎要高得多
我希望这有帮助
// Performance test, sum of an array
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = 0;
// Eval
console.time("eval");
for(var i = 0; i < 10000; i++) eval("result = (" + array.join("+") + ")");
console.timeEnd("eval");
// Loop
console.time("loop");
for(var i = 0; i < 10000; i++){
result = 0;
for(var j = 0; j < array.length; j++){
result += parseInt(array[j]);
}
}
console.timeEnd("loop");
// Reduce
console.time("reduce");
for(var i = 0; i < 10000; i++) result = array.reduce(function(pv, cv) { return pv + parseInt(cv); }, 0);
console.timeEnd("reduce");
// While
console.time("while");
for(var i = 0; i < 10000; i++){
j = array.length;
result = 0;
while(j--) result += array[i];
}
console.timeEnd("while");
//性能测试,数组的总和
var数组=[1,2,3,4,5,6,7,8,9,10];
var结果=0;
//评估
控制台。时间(“评估”);
对于(var i=0;i<10000;i++)eval(“结果=(“+array.join”(“+”)”);
控制台。时间结束(“评估”);
//环路
控制台时间(“循环”);
对于(变量i=0;i<10000;i++){
结果=0;
对于(var j=0;j
评估:5233.000ms
循环:255.000ms
减少:70.000ms
而:214.000ms最简单、最快、更可重用和更灵活的方法之一是:
Array.prototype.sum = function () {
for(var total = 0,l=this.length;l--;total+=this[l]); return total;
}
// usage
var array = [1,2,3,4,5,6,7,8,9,10];
array.sum()
或者你可以用邪恶的方式
var a = [1,2,3,4,5,6,7,8,9];
sum = eval(a.join("+"));
)() 两个肢体相加怎么样?这将把时间缩短一半。像这样: 1,2,3,4,5,6,7,8;总和=0 2,3,4,5,6,7;总和=10 3,4,5,6;总和=19 4,5;总和=28 总和=37 一种算法可以是:
function sum_array(arr){
let sum = 0,
length = arr.length,
half = Math.floor(length/2)
for (i = 0; i < half; i++) {
sum += arr[i] + arr[length - 1 - i]
}
if (length%2){
sum += arr[half]
}
return sum
}
函数和数组(arr){
设sum=0,
长度=arr.length,
一半=数学楼层(长度/2)
对于(i=0;i<一半;i++){
总和+=arr[i]+arr[length-1-i]
}
如果(长度%2){
总和+=arr[一半]
}
回报金额
}
使用performance.now()
在浏览器上测试时,它的执行速度更快。
我认为这是一个更好的方法。你们觉得怎么样?我试着用performance.now()来分析不同类型循环的性能。我取了一个非常大的数组,找到了数组中所有元素的总和。我每次运行代码三次,发现forEach和reduce显然是赢家 //For循环
let arr = [...Array(100000).keys()]
function addUsingForLoop(ar){
let sum = 0;
for(let i = 0; i < ar.length; i++){
sum += ar[i];
}
console.log(`Sum: ${sum}`);
return sum;
}
let t1 = performance.now();
addUsingForLoop(arr);
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 42.17500000959262 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 44.41999999107793 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 49.845000030472875 milliseconds"
//反向while循环
let arr = [...Array(100000).keys()]
function addUsingReverseWhileLoop(ar){
var sum = 0;
var i = ar.length;
while (i--) {
sum += ar[i];
}
console.log(`Sum: ${sum}`);
return sum;
}
var t1 = performance.now();
addUsingReverseWhileLoop(arr);
var t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 46.26999999163672 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 42.97000000951812 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 44.31500000646338 milliseconds"
//减少
let arr = [...Array(100000).keys()]
let t1 = performance.now();
sum = arr.reduce((pv, cv) => pv + cv, 0);
console.log(`Sum: ${sum}`)
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 4.654999997001141 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 5.040000018198043 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 4.835000028833747 milliseconds"
//弗雷奇
let arr = [...Array(100000).keys()]
function addUsingForEach(ar){
let sum = 0;
ar.forEach(item => {
sum += item;
})
console.log(`Sum: ${sum}`);
return sum
}
let t1 = performance.now();
addUsingForEach(arr)
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 5.315000016707927 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 5.869999993592501 mienter code herelliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 5.405000003520399 milliseconds"
测试!!!如果你想知道做某事最快的方法是什么,请尝试几种,然后测量结果。@Chad:很明显,我现在还没有“开箱思考”的时代。根据链接文档,“[reduce]可能不适用于所有浏览器”@Tim:这是在SpiderMonkey下运行的,不是任何特定的浏览器。啊,对不起,我错过了。在这种情况下,这就是答案。尽管
reduce
是一个本机函数,但不知何故我对此表示怀疑。在JS中面向性能的代码中,避免函数调用几乎总是更快,@BrunoLM这不再是事实!我的倒转速度稍微快一点,比没有快了很多次。@vol7ron,非常,非常,非常轻微,我们在谈论1000张唱片的~1ms:)是的,不是每次都是。尽管如此,我还是更倾向于使用(var i=0,n=a.length;iarr
来自于sum
方法吗?arr
真的应该是this
?似乎将while条件求值为布尔值会使它更快,因为循环几乎相等。我测试过,有时得到的增量方式比减量快。而Array.reduce是太慢了。@BrunoLM:你说得对,这是3年前的老答案。我想不久之后,有一些新的JS引擎可用,而现有的引擎经过调整,使正向循环比反向循环快。这说明了为什么微观优化通常是不明智的。我将继续测试和基准测试如果您没有本地套件,那么k--jsperf是一个很好的站点。链接的JS FIDLE在“For Loop:Length Caching(reverse)”中有一个错误。它总是将索引0处的元素添加到sum中。For(var i=0,n=array.Length;n>i;n--{sum+=array[i];}
应该更改为For(var i=0,n=array.length-1;n>=i;n--){sum+=array[n];}
。这使它与其他缓存循环处于相同的标准。Lol!这既不比reduce更简单,也不比reduce更快,也不比reduce更可重用,也不比reduce更灵活!这确实是最快的(请参阅),而且可以做到
function sum_array(arr){
let sum = 0,
length = arr.length,
half = Math.floor(length/2)
for (i = 0; i < half; i++) {
sum += arr[i] + arr[length - 1 - i]
}
if (length%2){
sum += arr[half]
}
return sum
}
let arr = [...Array(100000).keys()]
function addUsingForLoop(ar){
let sum = 0;
for(let i = 0; i < ar.length; i++){
sum += ar[i];
}
console.log(`Sum: ${sum}`);
return sum;
}
let t1 = performance.now();
addUsingForLoop(arr);
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 42.17500000959262 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 44.41999999107793 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 49.845000030472875 milliseconds"
let arr = [...Array(100000).keys()]
function addUsingWhileLoop(ar){
let sum = 0;
let index = 0;
while (index < ar.length) {
sum += ar[index];
index++;
}
console.log(`Sum: ${sum}`)
return sum;
}
let t1 = performance.now();
addUsingWhileLoop(arr);
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 44.2499999771826 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 44.01999997207895 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 41.71000001952052 milliseconds"
let arr = [...Array(100000).keys()]
function addUsingDoWhileLoop(ar){
let sum = 0;
let index = 0;
do {
sum += index;
index++;
} while (index < ar.length);
console.log(`Sum: ${sum}`);
return sum;
}
let t1 = performance.now();
addUsingDoWhileLoop(arr);
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 43.79500000504777 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 43.47500001313165 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 47.535000019706786 milliseconds"
let arr = [...Array(100000).keys()]
function addUsingReverseLoop(ar){
var sum=0;
for (var i=ar.length; i--;) {
sum+=arr[i];
}
console.log(`Sum: ${sum}`);
return sum;
}
let t1 = performance.now();
addUsingReverseLoop(arr);
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 46.199999982491136 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 44.96500000823289 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 43.880000011995435 milliseconds"
let arr = [...Array(100000).keys()]
function addUsingReverseWhileLoop(ar){
var sum = 0;
var i = ar.length;
while (i--) {
sum += ar[i];
}
console.log(`Sum: ${sum}`);
return sum;
}
var t1 = performance.now();
addUsingReverseWhileLoop(arr);
var t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 46.26999999163672 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 42.97000000951812 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 44.31500000646338 milliseconds"
let arr = [...Array(100000).keys()]
let t1 = performance.now();
sum = arr.reduce((pv, cv) => pv + cv, 0);
console.log(`Sum: ${sum}`)
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 4.654999997001141 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 5.040000018198043 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 4.835000028833747 milliseconds"
let arr = [...Array(100000).keys()]
function addUsingForEach(ar){
let sum = 0;
ar.forEach(item => {
sum += item;
})
console.log(`Sum: ${sum}`);
return sum
}
let t1 = performance.now();
addUsingForEach(arr)
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 5.315000016707927 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 5.869999993592501 mienter code herelliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 5.405000003520399 milliseconds"