Pull to refresh

Comments 8

Ни запушить, ни даже толком отладить на этом компьютере ничего не могу, поэтому код наверняка неправильный. Но идею демонстрирует.
Код
module.exports = class {
    constructor() {
        this._data = new Map;
        this._i32 = new Int32Array(2);
    }

    get([hi, lo]) {
        this._i32[0] = lo;
        this._i32[1] = hi;
        return this._data.get((new Float64Array(this._i32.buffer))[0]);
    }

    set([hi, lo], obj) {
        this._i32[0] = lo;
        this._i32[1] = hi;
        return this._data.set((new Float64Array(this._i32.buffer))[0]);
    }

    *entries() {
        for (const [key, obj] of this._data.entries()) {
            let [lo, hi] = new Int32Array(key.buffer);
            yield [[+hi, +lo], obj];
        }
    }
};
Не прокатило: там что то не сходится (скорее всего потому что не всякие 64 бита будут валидным `double`), но даже если бы сходилось, то получается в 3 раза медленнее чем list-based hashmap. Можно попробовать брать не все 64 бита, а скажем 60 (53 точно можно), а остальные складывать в небольшой массив (16 элементов если берём 60 бит).

Что-то в этом коде неправильно, но не могу понять что. Даже после исправлений в виде добавления , obj в метод set и создания массива в entries (key — число, у него нет буфера) он все еще выдает неправильный результат.


Кстати, у этого кода есть еще проблема с NaN и -0, но в тестах они не встречаются.

Именно в NAN/0 проблема. Если пара (lo, hi) превращается в NAN/0, я их отправляю в отдельный hashmap. Тогда всё работает и весьма быстро (но медленнее чем list-based hashmap): см. коммент в PR.

В последнем node его ещё нет.

Насколько я знаю, обновление V8 с 6.6 до 6.7 произойдёт уже скоро, ещё в Node.js 10.

Sign up to leave a comment.

Articles