Во время тестирования класса векторной обертки с отображением в памяти стало очевидно, что тот же код доступа к свойству, присоединенный к числовым свойствам, как минимум, в 100 раз медленнее, чем при присоединении к нечисловым свойствам:
class Vec2 {
constructor(buf, off) {
this.buf = new Float32Array(buf, off, 2);
}
get x() {
return this.buf[0];
}
get y() {
return this.buf[1];
}
set x(x) {
this.buf[0] = x;
}
set y(y) {
this.buf[1] = y;
}
get "0"() {
return this.buf[0];
}
get "1"() {
return this.buf[1];
}
set "0"(x) {
this.buf[0] = x;
}
set "1"(y) {
this.buf[1] = y;
}
}
const bench = require("@thi.ng/bench").bench;
const tx = require("@thi.ng/transducers");
const N = 10000;
const buf = new Float32Array(N * 2).fill(1);
const pts = [...tx.map((i) => new Vec2(buf.buffer, i * 8), tx.range(N))];
const updateXY = () => {
for (let i = 0; i < N; i++) {
pts[i].x += 1;
pts[i].y += 2;
}
};
const update01 = () => {
for (let i = 0; i < N; i++) {
pts[i]["0"] += 1;
pts[i]["1"] += 2;
}
};
bench(updateXY, 1000);
// 58ms
bench(update01, 1000);
// 6604ms
* 1004Может ли кто-нибудь объяснить возможные причины? Для этого конкретного случая здесь возможный обходной путь - расширение класса с
Float32Array
, что
делает заметным отличием (обе версии сейчас ~ 70 мс), но у меня вопрос более общий ...
class Vec2 extends Float32Array {
constructor(buf, off) {
super(buf, off, 2);
}
get x() {
return this[0];
}
get y() {
return this[1];
}
set x(x) {
this[0] = x;
}
set y(y) {
this[1] = y;
}
}