Skip to content

Instantly share code, notes, and snippets.

@GitaiQAQ
Last active May 16, 2020 16:07
Show Gist options
  • Select an option

  • Save GitaiQAQ/48736803de301c2eaa8d9d5d0d398182 to your computer and use it in GitHub Desktop.

Select an option

Save GitaiQAQ/48736803de301c2eaa8d9d5d0d398182 to your computer and use it in GitHub Desktop.
#!/bin/ts-node
const SymbolCache = Symbol.for("cache");
let miss = 0;
function computed(...args) {
const _cache = {};
return function (
target,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const _get = descriptor.get;
descriptor.get = function () {
this[SymbolCache] = this[SymbolCache] || {};
// console.log(this.name, propertyKey, args);
for (const key of args) {
const cacheData = this[SymbolCache][key];
const targetData = this[key];
if (this[key] instanceof Object) {
throw new Error("Computed properties cannot depend on Reference type.");
}
if (!(key in this[SymbolCache]) || cacheData != targetData) {
this[SymbolCache][propertyKey] = _get.call(this);
this[SymbolCache][key] = targetData;
return this[SymbolCache][propertyKey];
}
}
return this[SymbolCache][propertyKey];
}
};
}
let calcCounts = 0;
class TNode {
name: string;
childs?: TNode[];
defaultHeight: number = 10;
etag: number = Math.random();
constructor(name, childs) {
this.name = name;
this.childs = childs;
}
@computed("etag")
get childsHeight() {
miss++;
return this.childs &&
this.childs.reduce((prev, childNode) => prev + childNode.height, 0);
}
@computed("defaultHeight", "childsHeight")
get height() {
miss++;
return Math.max(this.defaultHeight, this.childs && this.childsHeight);
}
}
function testNodes(depth) {
if (depth == 5) return null;
return Array.from(new Array(10)).map((_, i) => new TNode(`child-${depth}-${i}`, testNodes(depth + 1)))
}
const root = new TNode("root", testNodes(1));
console.time("first");
console.log(root.height, miss);
console.timeEnd("first");
console.time("change");
for (let index = 0; index < 10; index++) {
miss = 0;
root.childs[0].childs[0].childs[0].childs.pop();
root.childs[0].childs[0].childs[0].etag = Math.random();
root.childs[0].childs[0].etag = Math.random();
root.childs[0].etag = Math.random();
root.etag = Math.random();
console.log(root.height, miss);
}
console.timeEnd("change");
miss = 0;
console.time("bc");
let tmp = 0;
for (let index = 0; index < 100000; index++) {
tmp += root.height;
}
console.log(root.height, miss);
console.timeEnd("bc");
@GitaiQAQ
Copy link
Author

GitaiQAQ commented May 16, 2020

$ ts-node index.ts
100000 12222
first: 9.639ms
99990 17
99980 8
99970 8
99960 8
99950 8
99940 8
99930 8
99920 8
99910 8
99910 5
change: 6.732ms
99910 0
bc: 45.749ms

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