Last active
May 16, 2020 16:07
-
-
Save GitaiQAQ/48736803de301c2eaa8d9d5d0d398182 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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"); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.