В вашем первом примере вы даете компилятору V8 много подсказок о том, что это за тип, поэтому нет никаких проблем с боксом / распаковкой.
Слегка измененная версия цикла for здесь.На моей машине цикл for теперь примерно в 5 раз быстрее, чем сокращение.
var len = 8e6
function *rands(){
for(let i =0; i < len; i++)
yield Math.random()
}
var add = (a,b) => a + b
var arr = new Float64Array([...rands()])
console.time('reduce')
var sum = arr.reduce(add)
console.log(sum)
console.timeEnd('reduce')
console.time('loop')
var sum = new Float64Array([0]);
for(var i = 0; i < len; i++)
sum[0] += arr[i];
console.log(sum[0])
console.timeEnd('loop')
Как вы можете видеть sum[0] += arr[i];
, теперь компилятору V8 легко узнать, что этот расчет использует Float64 для добавления, потому что и левая, и правая стороны должныбыть Float64.
Когда у вас есть -> sum += arr[i]
, правая сторона V8 знает, что это Float64, но левая сторона может быть чем угодно, это может быть целое число, строка или даже Float64, поэтомуV8 должен проверить, нужен ли ему бокс в Float64.
С помощью Reduce, опять же, подразумевается, что левая и правая части функции add будут Float64, потому что механизм v8 пересекает массивFloat64, a & b знает, что это будет Float64.