Интересно, насколько это медленно.
Соответствующий код JavaScript:
(function() {
"use strict";
var n = 10000;
var x = [];
var res = [];
for (var i = 0; i < n; i++) x.push(Math.random());
var t0 = Date.now();
for (var i = 0; i < 1000; i++) {
for (var j = 0; j < n; j++) {
x[j] += i;
}
res.push(x.reduce((a, b) => a + b));
}
var t1 = Date.now();
console.log("Milliseconds: " + (t1 - t0));
}());
работает всего за ~ 20 миллисекунд.
Итак, похожеDart каким-то образом запускает «медленный режим» для своего сгенерированного Javascript.
Если вы посмотрите на сгенерированный код, он содержит:
for (i = 0; i < 1000; ++i) {
for (j = 0; j < 10000; ++j) {
if (j >= x.length)
return H.ioore(x, j);
t1 = x[j];
if (typeof t1 !== "number")
return t1.$add();
C.JSArray_methods.$indexSet(x, j, t1 + i);
}
C.JSArray_methods.add$1(res, C.JSArray_methods.reduce$1(x, new A.main_closure0()));
}
Вы можете попытаться настроить этот код, но большойстоимость исходит от C.JSArray_methods.$indexSet(x, j, t1 + i);
. Если вы измените это значение на x[j] = t1 + i;
, время упадет до нескольких сотен миллисекунд. Итак, это проблема текущего кода.
(Вы можете немного улучшить производительность, ~ 20%, сделав x
List<num>
вместо List<double>
. Я понятия не имею, почемуэто имеет значение, сгенерированный код почти такой же, закрытие add
использует checkDouble
для проверки типа вместо checkNum
, но они имеют абсолютно одинаковое тело).
Вы не 'нужно избегать любых вычислений в браузере. Возможно, вам придется немного оптимизировать такие медленные случаи (или сообщить об этом разработчикам компилятора, потому что это, вероятно, может быть распознано и оптимизировано, но пока это не так). Например, вы можете изменить свой список x
парных чисел на Float64List
с dart:typed_data
:
var x = Float64List.fromList([for (var i = 0; i < n; i++) rand.nextDouble()]);
Тогда скорость значительно возрастет.