Skip to content

Commit 6521671

Browse files
committed
perf: implement a memoize decorator with smart caching
1 parent e0bbf1b commit 6521671

File tree

4 files changed

+139
-69
lines changed

4 files changed

+139
-69
lines changed

lib/common/decorators.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,90 @@ export function cache(): any {
5454
};
5555
}
5656

57+
interface MemoizeOptions {
58+
hashFn?: (...args: any[]) => any;
59+
shouldCache?: (result: any) => boolean;
60+
}
61+
let memoizeIDCounter = 0;
62+
export function memoize(options: MemoizeOptions): any {
63+
return (
64+
target: Object,
65+
propertyKey: string,
66+
descriptor: TypedPropertyDescriptor<any>
67+
): TypedPropertyDescriptor<any> => {
68+
// todo: remove once surely working as intended.
69+
const DEBUG = false;
70+
const memoizeID = memoizeIDCounter++;
71+
const valueOrGet: "value" | "get" = descriptor.value ? "value" : "get";
72+
const originalMethod = descriptor[valueOrGet];
73+
74+
descriptor[valueOrGet] = function (...args: any[]) {
75+
const cacheMapName = `__memoize_cache_map_${memoizeID}`;
76+
77+
DEBUG && console.log(options);
78+
let hashKey: any;
79+
if (options.hashFn) {
80+
DEBUG && console.log({ args });
81+
hashKey = options.hashFn.apply(this, args);
82+
} else {
83+
hashKey = `__memoize_cache_value_${memoizeID}`;
84+
}
85+
86+
DEBUG &&
87+
console.log({
88+
cacheMapName,
89+
hashKey,
90+
});
91+
92+
// initialize cache map if not exists
93+
if (!this.hasOwnProperty(cacheMapName)) {
94+
DEBUG && console.log("NO CACHE MAP YET, CREATING ONE NOW");
95+
Object.defineProperty(this, cacheMapName, {
96+
configurable: false,
97+
enumerable: false,
98+
writable: false,
99+
value: new Map<any, any>(),
100+
});
101+
}
102+
const cacheMap: Map<any, any> = this[cacheMapName];
103+
104+
DEBUG &&
105+
console.log({
106+
cacheMap,
107+
});
108+
109+
// check if has memoized value based on hashFn
110+
if (cacheMap.has(hashKey)) {
111+
DEBUG && console.log("CACHE HIT");
112+
// if yes, return cached value
113+
return cacheMap.get(hashKey);
114+
}
115+
DEBUG && console.log("CACHE MISS");
116+
117+
// if not call original and get result
118+
const result = originalMethod.apply(this, args);
119+
120+
// call shouldCache (if passed) with the result or default to true
121+
let shouldCache: boolean = true;
122+
if (options.shouldCache) {
123+
shouldCache = options.shouldCache.call(this, result);
124+
}
125+
126+
DEBUG && console.log("GOT BACK SHOULDCACHE", shouldCache);
127+
128+
if (shouldCache) {
129+
DEBUG && console.log("CACHING NOW");
130+
cacheMap.set(hashKey, result);
131+
}
132+
// if shouldCache: save result
133+
DEBUG && console.log("RETURNING", result);
134+
return result;
135+
};
136+
137+
return descriptor;
138+
};
139+
}
140+
57141
/**
58142
* Calls specific method of the instance before executing the decorated method.
59143
* This is usable when some of your methods depend on initialize async method, that cannot be invoked in constructor of the class.

lib/services/project-data-service.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
SRC_DIR,
1414
} from "../constants";
1515
import { parseJson } from "../common/helpers";
16-
import { exported } from "../common/decorators";
16+
import { exported, memoize } from "../common/decorators";
1717
import {
1818
IAssetGroup,
1919
IAssetItem,
@@ -595,6 +595,20 @@ export class ProjectDataService implements IProjectDataService {
595595
return this.getInstalledRuntimePackage(projectDir, platform);
596596
}
597597

598+
@memoize({
599+
hashFn(projectDir: string, platform: constants.SupportedPlatform) {
600+
return projectDir + ":" + platform;
601+
},
602+
shouldCache(result: IBasePluginData) {
603+
// don't cache coerced versions
604+
if ((result as any)._coerced) {
605+
return false;
606+
}
607+
608+
// only cache if version is defined
609+
return !!result.version;
610+
},
611+
})
598612
private getInstalledRuntimePackage(
599613
projectDir: string,
600614
platform: constants.SupportedPlatform

package-lock.json

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

yarn.lock

Lines changed: 36 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"pixelmatch" "^4.0.2"
6565
"tinycolor2" "^1.4.1"
6666

67-
"@jimp/custom@^0.14.0":
67+
"@jimp/custom@^0.14.0", "@jimp/custom@>=0.3.5":
6868
"integrity" "sha512-kQJMeH87+kWJdVw8F9GQhtsageqqxrvzg7yyOw3Tx/s7v5RToe8RnKyMM+kVtBJtNAG+Xyv/z01uYQ2jiZ3GwA=="
6969
"resolved" "https://registry.npmjs.org/@jimp/custom/-/custom-0.14.0.tgz"
7070
"version" "0.14.0"
@@ -91,15 +91,15 @@
9191
"@jimp/utils" "^0.14.0"
9292
"jpeg-js" "^0.4.0"
9393

94-
"@jimp/plugin-blit@^0.14.0":
94+
"@jimp/plugin-blit@^0.14.0", "@jimp/plugin-blit@>=0.3.5":
9595
"integrity" "sha512-YoYOrnVHeX3InfgbJawAU601iTZMwEBZkyqcP1V/S33Qnz9uzH1Uj1NtC6fNgWzvX6I4XbCWwtr4RrGFb5CFrw=="
9696
"resolved" "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.14.0.tgz"
9797
"version" "0.14.0"
9898
dependencies:
9999
"@babel/runtime" "^7.7.2"
100100
"@jimp/utils" "^0.14.0"
101101

102-
"@jimp/plugin-blur@^0.14.0":
102+
"@jimp/plugin-blur@^0.14.0", "@jimp/plugin-blur@>=0.3.5":
103103
"integrity" "sha512-9WhZcofLrT0hgI7t0chf7iBQZib//0gJh9WcQMUt5+Q1Bk04dWs8vTgLNj61GBqZXgHSPzE4OpCrrLDBG8zlhQ=="
104104
"resolved" "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.14.0.tgz"
105105
"version" "0.14.0"
@@ -115,7 +115,7 @@
115115
"@babel/runtime" "^7.7.2"
116116
"@jimp/utils" "^0.14.0"
117117

118-
"@jimp/plugin-color@^0.14.0":
118+
"@jimp/plugin-color@^0.14.0", "@jimp/plugin-color@>=0.8.0":
119119
"integrity" "sha512-JJz512SAILYV0M5LzBb9sbOm/XEj2fGElMiHAxb7aLI6jx+n0agxtHpfpV/AePTLm1vzzDxx6AJxXbKv355hBQ=="
120120
"resolved" "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.14.0.tgz"
121121
"version" "0.14.0"
@@ -140,7 +140,7 @@
140140
"@babel/runtime" "^7.7.2"
141141
"@jimp/utils" "^0.14.0"
142142

143-
"@jimp/plugin-crop@^0.14.0":
143+
"@jimp/plugin-crop@^0.14.0", "@jimp/plugin-crop@>=0.3.5":
144144
"integrity" "sha512-Ojtih+XIe6/XSGtpWtbAXBozhCdsDMmy+THUJAGu2x7ZgKrMS0JotN+vN2YC3nwDpYkM+yOJImQeptSfZb2Sug=="
145145
"resolved" "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.14.0.tgz"
146146
"version" "0.14.0"
@@ -221,23 +221,23 @@
221221
"@jimp/utils" "^0.14.0"
222222
"load-bmfont" "^1.4.0"
223223

224-
"@jimp/plugin-resize@^0.14.0":
224+
"@jimp/plugin-resize@^0.14.0", "@jimp/plugin-resize@>=0.3.5", "@jimp/plugin-resize@>=0.8.0":
225225
"integrity" "sha512-qFeMOyXE/Bk6QXN0GQo89+CB2dQcXqoxUcDb2Ah8wdYlKqpi53skABkgVy5pW3EpiprDnzNDboMltdvDslNgLQ=="
226226
"resolved" "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.14.0.tgz"
227227
"version" "0.14.0"
228228
dependencies:
229229
"@babel/runtime" "^7.7.2"
230230
"@jimp/utils" "^0.14.0"
231231

232-
"@jimp/plugin-rotate@^0.14.0":
232+
"@jimp/plugin-rotate@^0.14.0", "@jimp/plugin-rotate@>=0.3.5":
233233
"integrity" "sha512-aGaicts44bvpTcq5Dtf93/8TZFu5pMo/61lWWnYmwJJU1RqtQlxbCLEQpMyRhKDNSfPbuP8nyGmaqXlM/82J0Q=="
234234
"resolved" "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.14.0.tgz"
235235
"version" "0.14.0"
236236
dependencies:
237237
"@babel/runtime" "^7.7.2"
238238
"@jimp/utils" "^0.14.0"
239239

240-
"@jimp/plugin-scale@^0.14.0":
240+
"@jimp/plugin-scale@^0.14.0", "@jimp/plugin-scale@>=0.3.5":
241241
"integrity" "sha512-ZcJk0hxY5ZKZDDwflqQNHEGRblgaR+piePZm7dPwPUOSeYEH31P0AwZ1ziceR74zd8N80M0TMft+e3Td6KGBHw=="
242242
"resolved" "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.14.0.tgz"
243243
"version" "0.14.0"
@@ -1188,13 +1188,6 @@
11881188
"resolved" "https://registry.npmjs.org/binaryextensions/-/binaryextensions-4.13.0.tgz"
11891189
"version" "4.13.0"
11901190

1191-
"bindings@^1.5.0":
1192-
"integrity" "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="
1193-
"resolved" "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz"
1194-
"version" "1.5.0"
1195-
dependencies:
1196-
"file-uri-to-path" "1.0.0"
1197-
11981191
"bmp-js@^0.1.0":
11991192
"integrity" "sha1-4Fpj95amwf8l9Hcex62twUjAcjM="
12001193
"resolved" "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz"
@@ -1447,7 +1440,7 @@
14471440
dependencies:
14481441
"check-error" "^1.0.2"
14491442

1450-
"chai@4.2.0":
1443+
"chai@>= 2.1.2 < 5", "chai@4.2.0":
14511444
"integrity" "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw=="
14521445
"resolved" "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz"
14531446
"version" "4.2.0"
@@ -2349,7 +2342,7 @@
23492342
dependencies:
23502343
"once" "^1.4.0"
23512344

2352-
"enquirer@^2.3.6":
2345+
"enquirer@^2.3.6", "enquirer@>= 2.3.0 < 3":
23532346
"integrity" "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg=="
23542347
"resolved" "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz"
23552348
"version" "2.3.6"
@@ -2674,7 +2667,7 @@
26742667
"resolved" "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz"
26752668
"version" "9.0.0"
26762669

2677-
"file-uri-to-path@1", "file-uri-to-path@1.0.0":
2670+
"file-uri-to-path@1":
26782671
"integrity" "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
26792672
"resolved" "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz"
26802673
"version" "1.0.0"
@@ -2886,24 +2879,6 @@
28862879
"resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
28872880
"version" "1.0.0"
28882881

2889-
"fsevents@^1.2.7":
2890-
"integrity" "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw=="
2891-
"resolved" "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz"
2892-
"version" "1.2.13"
2893-
dependencies:
2894-
"bindings" "^1.5.0"
2895-
"nan" "^2.12.1"
2896-
2897-
"fsevents@~2.1.2":
2898-
"integrity" "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ=="
2899-
"resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz"
2900-
"version" "2.1.3"
2901-
2902-
"fsevents@~2.3.1":
2903-
"integrity" "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="
2904-
"resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
2905-
"version" "2.3.2"
2906-
29072882
"ftp@~0.3.10":
29082883
"integrity" "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0="
29092884
"resolved" "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz"
@@ -3293,7 +3268,7 @@
32933268
"semver" "^5.3.0"
32943269
"strip-bom" "^2.0.0"
32953270

3296-
"grunt@1.2.1":
3271+
"grunt@^1.0.0 || ^0.4.0", "grunt@>=0.4.0", "grunt@>=0.4.5", "grunt@>=1", "grunt@1.2.1":
32973272
"integrity" "sha512-zgJjn9N56tScvRt/y0+1QA+zDBnKTrkpyeSBqQPLcZvbqTD/oyGMrdZQXmm6I3828s+FmPvxc3Xv+lgKFtudOw=="
32983273
"resolved" "https://registry.npmjs.org/grunt/-/grunt-1.2.1.tgz"
32993274
"version" "1.2.1"
@@ -4575,7 +4550,7 @@
45754550
"lodash.assign" "^4.2.0"
45764551
"node-emoji" "^1.4.1"
45774552

4578-
"marked@1.1.1":
4553+
"marked@^0.4.0 || ^0.5.0", "marked@1.1.1":
45794554
"integrity" "sha512-mJzT8D2yPxoPh7h0UXkB+dBj4FykPJ2OIfxAWeIHrvoHDkFxukV/29QxoFQoPM6RLEwhIFdJpmKBlqVM3s2ZIw=="
45804555
"resolved" "https://registry.npmjs.org/marked/-/marked-1.1.1.tgz"
45814556
"version" "1.1.1"
@@ -4956,11 +4931,6 @@
49564931
"resolved" "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz"
49574932
"version" "0.0.8"
49584933

4959-
"nan@^2.12.1":
4960-
"integrity" "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
4961-
"resolved" "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz"
4962-
"version" "2.14.1"
4963-
49644934
"nanoid@^1.0.7":
49654935
"integrity" "sha512-4ug4BsuHxiVHoRUe1ud6rUFT3WUMmjXt1W0quL0CviZQANdan7D8kqN5/maw53hmAApY/jfzMRkC57BNNs60ZQ=="
49664936
"resolved" "https://registry.npmjs.org/nanoid/-/nanoid-1.3.4.tgz"
@@ -7000,7 +6970,7 @@
70006970
"debug" "^3.1.0"
70016971
"proxy-agent" "2"
70026972

7003-
"superagent@^3.8.1":
6973+
"superagent@^3.8.1", "superagent@>= 0.15.4 || 1 || 2 || 3":
70046974
"integrity" "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA=="
70056975
"resolved" "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz"
70066976
"version" "3.8.3"
@@ -7274,23 +7244,7 @@
72747244
dependencies:
72757245
"tsutils" "^2.27.2 <2.29.0"
72767246

7277-
"tslint@5.4.3":
7278-
"integrity" "sha1-dhyEArgONHt3M6BDkKdXslNYBGc="
7279-
"resolved" "https://registry.npmjs.org/tslint/-/tslint-5.4.3.tgz"
7280-
"version" "5.4.3"
7281-
dependencies:
7282-
"babel-code-frame" "^6.22.0"
7283-
"colors" "^1.1.2"
7284-
"commander" "^2.9.0"
7285-
"diff" "^3.2.0"
7286-
"glob" "^7.1.1"
7287-
"minimatch" "^3.0.4"
7288-
"resolve" "^1.3.2"
7289-
"semver" "^5.3.0"
7290-
"tslib" "^1.7.1"
7291-
"tsutils" "^2.3.0"
7292-
7293-
"tslint@6.1.3":
7247+
"tslint@^5.1.0", "tslint@6.1.3":
72947248
"integrity" "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg=="
72957249
"resolved" "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz"
72967250
"version" "6.1.3"
@@ -7309,6 +7263,22 @@
73097263
"tslib" "^1.13.0"
73107264
"tsutils" "^2.29.0"
73117265

7266+
"tslint@5.4.3":
7267+
"integrity" "sha1-dhyEArgONHt3M6BDkKdXslNYBGc="
7268+
"resolved" "https://registry.npmjs.org/tslint/-/tslint-5.4.3.tgz"
7269+
"version" "5.4.3"
7270+
dependencies:
7271+
"babel-code-frame" "^6.22.0"
7272+
"colors" "^1.1.2"
7273+
"commander" "^2.9.0"
7274+
"diff" "^3.2.0"
7275+
"glob" "^7.1.1"
7276+
"minimatch" "^3.0.4"
7277+
"resolve" "^1.3.2"
7278+
"semver" "^5.3.0"
7279+
"tslib" "^1.7.1"
7280+
"tsutils" "^2.3.0"
7281+
73127282
"tsutils@^2.27.2 <2.29.0":
73137283
"integrity" "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA=="
73147284
"resolved" "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz"
@@ -7372,16 +7342,16 @@
73727342
"resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz"
73737343
"version" "0.8.1"
73747344

7345+
"typescript@^2.1.0 || ^3.0.0", "typescript@>=1", "typescript@>=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev", "typescript@>=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev", "typescript@>=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev", "typescript@3.9.7":
7346+
"integrity" "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw=="
7347+
"resolved" "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz"
7348+
"version" "3.9.7"
7349+
73757350
"typescript@~4.0.2":
73767351
"integrity" "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ=="
73777352
"resolved" "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz"
73787353
"version" "4.0.2"
73797354

7380-
"typescript@3.9.7":
7381-
"integrity" "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw=="
7382-
"resolved" "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz"
7383-
"version" "3.9.7"
7384-
73857355
"uglify-js@^3.1.4":
73867356
"integrity" "sha512-Lh00i69Uf6G74mvYpHCI9KVVXLcHW/xu79YTvH7Mkc9zyKUeSPz0owW0dguj0Scavns3ZOh3wY63J0Zb97Za2g=="
73877357
"resolved" "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.3.tgz"

0 commit comments

Comments
 (0)