Найти длину строки на 300 * медленнее
Сначала я прочитал ответ на вопрос Почему моя функция WebAssembly медленнее, чем эквивалент в JavaScript?
Но это пролило немного света на эту проблему, и я потратил много времени, которое вполне может быть желтым на стене.
Я не использую глобалы, я не использую память. У меня есть две простые функции, которые находят длину отрезка и сравнивают их с одним и тем же в простом старом Javascript. У меня есть 4 параметра и еще 3 локальных, и я возвращаю число с плавающей или двойной.
В Chrome Javascript в 40 раз быстрее, чем webAssembly, а в Firefox wasm почти в 300 раз медленнее, чем Javascript.
контрольный пример jsPref.
Я добавил тестовый пример в jsPref WebAssembly V Javascript math
Что я делаю не так?
Либо
- Я пропустил очевидную ошибку, плохую практику или страдаю от глупости кодера.
- WebAssembly не для 32-битной ОС (выиграть 10 ноутбуков i7CPU)
- WebAssembly далека от готовой технологии.
Пожалуйста, выберите вариант 1.
Я прочитал пример использования веб-сборки
Повторно использовать существующий код, ориентируясь на WebAssembly, встроенный в более крупный JavaScript/HTML приложение. Это может быть что угодно из простого вспомогательные библиотеки для разгрузки задач, ориентированных на вычисления.
Я надеялся, что смогу заменить некоторые геометрические библиотеки на webAssembly, чтобы получить дополнительную производительность. Я надеялся, что это будет круто, в 10 и более раз быстрее. НО в 300 раз медленнее WTF.
UPADTE
Это не проблема оптимизации JS.
Чтобы убедиться, что оптимизация имеет минимально возможный эффект, я проверил следующие методы, чтобы уменьшить или устранить любые ошибки оптимизации.
- счетчик
c += length(...
, чтобы убедиться, что весь код выполняется. bigCount += c
для обеспечения выполнения всей функции. Не требуется- 4 строки для каждой функции, чтобы уменьшить наклон наклона. Не требуется
- все значения случайным образом генерируются двойными числами
- каждый вызов функции возвращает свой результат.
- добавьте более медленное вычисление длины в JS, используя
Math.hypot
, чтобы доказать, что код выполняется. - добавлен пустой вызов, который возвращает первый параметр JS, чтобы увидеть накладные расходы
// setup and associated functions
const setOf = (count, callback) => {var a = [],i = 0; while (i < count) { a.push(callback(i ++)) } return a };
const rand = (min = 1, max = min + (min = 0)) => Math.random() * (max - min) + min;
const a = setOf(100009,i=>rand(-100000,100000));
var bigCount = 0;
function len(x,y,x1,y1){
var nx = x1 - x;
var ny = y1 - y;
return Math.sqrt(nx * nx + ny * ny);
}
function lenSlow(x,y,x1,y1){
var nx = x1 - x;
var ny = y1 - y;
return Math.hypot(nx,ny);
}
function lenEmpty(x,y,x1,y1){
return x;
}
// Test functions in same scope as above. None is in global scope
// Each function is copied 4 time and tests are performed randomly.
// c += length(... to ensure all code is executed.
// bigCount += c to ensure whole function is executed.
// 4 lines for each function to reduce a inlining skew
// all values are randomly generated doubles
// each function call returns a different result.
tests : [{
func : function (){
var i,c=0,a1,a2,a3,a4;
for (i = 0; i < 10000; i += 1) {
a1 = a[i];
a2 = a[i+1];
a3 = a[i+2];
a4 = a[i+3];
c += length(a1,a2,a3,a4);
c += length(a2,a3,a4,a1);
c += length(a3,a4,a1,a2);
c += length(a4,a1,a2,a3);
}
bigCount = (bigCount + c) % 1000;
},
name : "length64",
},{
func : function (){
var i,c=0,a1,a2,a3,a4;
for (i = 0; i < 10000; i += 1) {
a1 = a[i];
a2 = a[i+1];
a3 = a[i+2];
a4 = a[i+3];
c += lengthF(a1,a2,a3,a4);
c += lengthF(a2,a3,a4,a1);
c += lengthF(a3,a4,a1,a2);
c += lengthF(a4,a1,a2,a3);
}
bigCount = (bigCount + c) % 1000;
},
name : "length32",
},{
func : function (){
var i,c=0,a1,a2,a3,a4;
for (i = 0; i < 10000; i += 1) {
a1 = a[i];
a2 = a[i+1];
a3 = a[i+2];
a4 = a[i+3];
c += len(a1,a2,a3,a4);
c += len(a2,a3,a4,a1);
c += len(a3,a4,a1,a2);
c += len(a4,a1,a2,a3);
}
bigCount = (bigCount + c) % 1000;
},
name : "length JS",
},{
func : function (){
var i,c=0,a1,a2,a3,a4;
for (i = 0; i < 10000; i += 1) {
a1 = a[i];
a2 = a[i+1];
a3 = a[i+2];
a4 = a[i+3];
c += lenSlow(a1,a2,a3,a4);
c += lenSlow(a2,a3,a4,a1);
c += lenSlow(a3,a4,a1,a2);
c += lenSlow(a4,a1,a2,a3);
}
bigCount = (bigCount + c) % 1000;
},
name : "Length JS Slow",
},{
func : function (){
var i,c=0,a1,a2,a3,a4;
for (i = 0; i < 10000; i += 1) {
a1 = a[i];
a2 = a[i+1];
a3 = a[i+2];
a4 = a[i+3];
c += lenEmpty(a1,a2,a3,a4);
c += lenEmpty(a2,a3,a4,a1);
c += lenEmpty(a3,a4,a1,a2);
c += lenEmpty(a4,a1,a2,a3);
}
bigCount = (bigCount + c) % 1000;
},
name : "Empty",
}
],