Skip to content

Instantly share code, notes, and snippets.

@zenparsing
Created January 6, 2020 00:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zenparsing/13bb7dfa4f9fec27a9a5219589c3b48e to your computer and use it in GitHub Desktop.
Save zenparsing/13bb7dfa4f9fec27a9a5219589c3b48e to your computer and use it in GitHub Desktop.
SlotMap from private fields
/*
A map class, implemented with private slots, which has the following properties:
- The presence of a mapping k => v in a SlotMap does not by itself make k or v reachable
- For each mapping k => v in a SlotMap m (whether m is reachable or not), if k is reachable then v is reachable
*/
const DELETED = {};
function createCtor() {
return class extends (function(x) { return x }) {
#slot;
constructor(key, value) {
super(key);
this.#slot = value;
}
static get(key) {
try {
const value = key.#slot;
if (value !== DELETED)
return value;
} catch (x) {}
return undefined;
}
static set(key, value) {
try { key.#slot = value }
catch (x) { new this(key, value) }
return this;
}
static has(key) {
try { return key.#slot !== DELETED }
catch (x) { return false }
}
static delete(key) {
try {
if (key.#slot !== DELETED) {
key.#slot = DELETED;
return true;
}
} catch (x) {}
return false;
}
};
}
class SlotMap {
#ctor;
constructor() { this.#ctor = createCtor() }
get(key) { return this.#ctor.get(key) }
set(key, value) { return this.#ctor.set(key, value) }
delete(key) { return this.#ctor.delete(key) }
has(key) { return this.#ctor.has(key) }
}
function time(fn, msg) {
return (...args) => {
let start = Date.now();
let result = fn(...args);
console.log(`${ msg }: ${ Date.now() - start }`);
return result;
};
}
function testMap(constructor) {
let map = new constructor();
for (let i = 0; i < 100000; ++i) {
let obj = {};
map.set(obj, 123);
let value = map.get(obj);
}
}
time(testMap, 'SlotMap')(SlotMap);
time(testMap, 'WeakMap')(WeakMap);
time(testMap, 'SlotMap')(SlotMap);
time(testMap, 'WeakMap')(WeakMap);
@zenparsing
Copy link
Author

With node v13.5.0:

SlotMap: 1051
WeakMap: 90
SlotMap: 1375
WeakMap: 93

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment