Я вычисляю второй необработанный момент больших массивов в Node и пытаюсь найти способы сделать его быстрее. Интересно, что это стало намного быстрее, просто добавив +
.
Вот оригинальная функция:
const fn = (arr) => arr.reduce((sum, x) => sum + x**2, 0);
Вот модифицированная функция, которая примерно на 33% быстрее:
const fn2 = (arr) => arr.reduce((sum, x) => sum + (+x)**2, 0);
Это примерно та же скорость, что и у модифицированной функции:
const fn3 = (arr) => arr.reduce((sum, x) => sum + (12.34 + x)**2, 0);
Вот код для получения среднего времени:
const avgTime = (fn) => {
let sum = 0;
for (let i = 0; i < 100; i++){
const hrTime = process.hrtime();
const startTime = hrTime[0] * 1000000 + hrTime[1] / 1000;
fn();
const hrTime2 = process.hrtime();
sum += hrTime2[0] * 1000000 + hrTime2[1] / 1000 - startTime;
}
return sum / 100;
}
const arr = Array(1000000).fill(0).map(_ => Math.random());
avgTime(() => fn(arr));
avgTime(() => fn2(arr));
avgTime(() => fn3(arr));
Я знаю, что движок JS оптимизирует, если знает тип переменной, поэтому asm.js добавляет |0
в конец целых чисел. Однако в этом случае, поскольку я использую **
для переменной x
, разве движок уже не должен знать, что это число? Почему добавление +
помогает?
Кроме того, есть ли способы сделать это еще быстрее без использования графического процессора? (Все библиотеки GPU используют CUDA, которого у меня нет.)