Почему доступ к числовому свойству в 100 раз медленнее? - PullRequest
4 голосов
/ 14 октября 2019

Во время тестирования класса векторной обертки с отображением в памяти стало очевидно, что тот же код доступа к свойству, присоединенный к числовым свойствам, как минимум, в 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...