Skip to content

Commit

Permalink
perf: implement a memoize decorator with smart caching
Browse files Browse the repository at this point in the history
  • Loading branch information
rigor789 committed Sep 10, 2021
1 parent e0bbf1b commit 6521671
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 69 deletions.
84 changes: 84 additions & 0 deletions lib/common/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,90 @@ export function cache(): any {
};
}

interface MemoizeOptions {
hashFn?: (...args: any[]) => any;
shouldCache?: (result: any) => boolean;
}
let memoizeIDCounter = 0;
export function memoize(options: MemoizeOptions): any {
return (
target: Object,
propertyKey: string,
descriptor: TypedPropertyDescriptor<any>
): TypedPropertyDescriptor<any> => {
// todo: remove once surely working as intended.
const DEBUG = false;
const memoizeID = memoizeIDCounter++;
const valueOrGet: "value" | "get" = descriptor.value ? "value" : "get";
const originalMethod = descriptor[valueOrGet];

descriptor[valueOrGet] = function (...args: any[]) {
const cacheMapName = `__memoize_cache_map_${memoizeID}`;

DEBUG && console.log(options);
let hashKey: any;
if (options.hashFn) {
DEBUG && console.log({ args });
hashKey = options.hashFn.apply(this, args);
} else {
hashKey = `__memoize_cache_value_${memoizeID}`;
}

DEBUG &&
console.log({
cacheMapName,
hashKey,
});

// initialize cache map if not exists
if (!this.hasOwnProperty(cacheMapName)) {
DEBUG && console.log("NO CACHE MAP YET, CREATING ONE NOW");
Object.defineProperty(this, cacheMapName, {
configurable: false,
enumerable: false,
writable: false,
value: new Map<any, any>(),
});
}
const cacheMap: Map<any, any> = this[cacheMapName];

DEBUG &&
console.log({
cacheMap,
});

// check if has memoized value based on hashFn
if (cacheMap.has(hashKey)) {
DEBUG && console.log("CACHE HIT");
// if yes, return cached value
return cacheMap.get(hashKey);
}
DEBUG && console.log("CACHE MISS");

// if not call original and get result
const result = originalMethod.apply(this, args);

// call shouldCache (if passed) with the result or default to true
let shouldCache: boolean = true;
if (options.shouldCache) {
shouldCache = options.shouldCache.call(this, result);
}

DEBUG && console.log("GOT BACK SHOULDCACHE", shouldCache);

if (shouldCache) {
DEBUG && console.log("CACHING NOW");
cacheMap.set(hashKey, result);
}
// if shouldCache: save result
DEBUG && console.log("RETURNING", result);
return result;
};

return descriptor;
};
}

/**
* Calls specific method of the instance before executing the decorated method.
* This is usable when some of your methods depend on initialize async method, that cannot be invoked in constructor of the class.
Expand Down
16 changes: 15 additions & 1 deletion lib/services/project-data-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
SRC_DIR,
} from "../constants";
import { parseJson } from "../common/helpers";
import { exported } from "../common/decorators";
import { exported, memoize } from "../common/decorators";
import {
IAssetGroup,
IAssetItem,
Expand Down Expand Up @@ -595,6 +595,20 @@ export class ProjectDataService implements IProjectDataService {
return this.getInstalledRuntimePackage(projectDir, platform);
}

@memoize({
hashFn(projectDir: string, platform: constants.SupportedPlatform) {
return projectDir + ":" + platform;
},
shouldCache(result: IBasePluginData) {
// don't cache coerced versions
if ((result as any)._coerced) {
return false;
}

// only cache if version is defined
return !!result.version;
},
})
private getInstalledRuntimePackage(
projectDir: string,
platform: constants.SupportedPlatform
Expand Down
6 changes: 4 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

102 changes: 36 additions & 66 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"pixelmatch" "^4.0.2"
"tinycolor2" "^1.4.1"

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

"@jimp/plugin-blit@^0.14.0":
"@jimp/plugin-blit@^0.14.0", "@jimp/plugin-blit@>=0.3.5":
"integrity" "sha512-YoYOrnVHeX3InfgbJawAU601iTZMwEBZkyqcP1V/S33Qnz9uzH1Uj1NtC6fNgWzvX6I4XbCWwtr4RrGFb5CFrw=="
"resolved" "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.14.0.tgz"
"version" "0.14.0"
dependencies:
"@babel/runtime" "^7.7.2"
"@jimp/utils" "^0.14.0"

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

"@jimp/plugin-color@^0.14.0":
"@jimp/plugin-color@^0.14.0", "@jimp/plugin-color@>=0.8.0":
"integrity" "sha512-JJz512SAILYV0M5LzBb9sbOm/XEj2fGElMiHAxb7aLI6jx+n0agxtHpfpV/AePTLm1vzzDxx6AJxXbKv355hBQ=="
"resolved" "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.14.0.tgz"
"version" "0.14.0"
Expand All @@ -140,7 +140,7 @@
"@babel/runtime" "^7.7.2"
"@jimp/utils" "^0.14.0"

"@jimp/plugin-crop@^0.14.0":
"@jimp/plugin-crop@^0.14.0", "@jimp/plugin-crop@>=0.3.5":
"integrity" "sha512-Ojtih+XIe6/XSGtpWtbAXBozhCdsDMmy+THUJAGu2x7ZgKrMS0JotN+vN2YC3nwDpYkM+yOJImQeptSfZb2Sug=="
"resolved" "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.14.0.tgz"
"version" "0.14.0"
Expand Down Expand Up @@ -221,23 +221,23 @@
"@jimp/utils" "^0.14.0"
"load-bmfont" "^1.4.0"

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

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

"@jimp/plugin-scale@^0.14.0":
"@jimp/plugin-scale@^0.14.0", "@jimp/plugin-scale@>=0.3.5":
"integrity" "sha512-ZcJk0hxY5ZKZDDwflqQNHEGRblgaR+piePZm7dPwPUOSeYEH31P0AwZ1ziceR74zd8N80M0TMft+e3Td6KGBHw=="
"resolved" "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.14.0.tgz"
"version" "0.14.0"
Expand Down Expand Up @@ -1188,13 +1188,6 @@
"resolved" "https://registry.npmjs.org/binaryextensions/-/binaryextensions-4.13.0.tgz"
"version" "4.13.0"

"bindings@^1.5.0":
"integrity" "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="
"resolved" "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz"
"version" "1.5.0"
dependencies:
"file-uri-to-path" "1.0.0"

"bmp-js@^0.1.0":
"integrity" "sha1-4Fpj95amwf8l9Hcex62twUjAcjM="
"resolved" "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz"
Expand Down Expand Up @@ -1447,7 +1440,7 @@
dependencies:
"check-error" "^1.0.2"

"chai@4.2.0":
"chai@>= 2.1.2 < 5", "chai@4.2.0":
"integrity" "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw=="
"resolved" "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz"
"version" "4.2.0"
Expand Down Expand Up @@ -2349,7 +2342,7 @@
dependencies:
"once" "^1.4.0"

"enquirer@^2.3.6":
"enquirer@^2.3.6", "enquirer@>= 2.3.0 < 3":
"integrity" "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg=="
"resolved" "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz"
"version" "2.3.6"
Expand Down Expand Up @@ -2674,7 +2667,7 @@
"resolved" "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz"
"version" "9.0.0"

"file-uri-to-path@1", "file-uri-to-path@1.0.0":
"file-uri-to-path@1":
"integrity" "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
"resolved" "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz"
"version" "1.0.0"
Expand Down Expand Up @@ -2886,24 +2879,6 @@
"resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
"version" "1.0.0"

"fsevents@^1.2.7":
"integrity" "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw=="
"resolved" "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz"
"version" "1.2.13"
dependencies:
"bindings" "^1.5.0"
"nan" "^2.12.1"

"fsevents@~2.1.2":
"integrity" "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ=="
"resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz"
"version" "2.1.3"

"fsevents@~2.3.1":
"integrity" "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="
"resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
"version" "2.3.2"

"ftp@~0.3.10":
"integrity" "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0="
"resolved" "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz"
Expand Down Expand Up @@ -3293,7 +3268,7 @@
"semver" "^5.3.0"
"strip-bom" "^2.0.0"

"grunt@1.2.1":
"grunt@^1.0.0 || ^0.4.0", "grunt@>=0.4.0", "grunt@>=0.4.5", "grunt@>=1", "grunt@1.2.1":
"integrity" "sha512-zgJjn9N56tScvRt/y0+1QA+zDBnKTrkpyeSBqQPLcZvbqTD/oyGMrdZQXmm6I3828s+FmPvxc3Xv+lgKFtudOw=="
"resolved" "https://registry.npmjs.org/grunt/-/grunt-1.2.1.tgz"
"version" "1.2.1"
Expand Down Expand Up @@ -4575,7 +4550,7 @@
"lodash.assign" "^4.2.0"
"node-emoji" "^1.4.1"

"marked@1.1.1":
"marked@^0.4.0 || ^0.5.0", "marked@1.1.1":
"integrity" "sha512-mJzT8D2yPxoPh7h0UXkB+dBj4FykPJ2OIfxAWeIHrvoHDkFxukV/29QxoFQoPM6RLEwhIFdJpmKBlqVM3s2ZIw=="
"resolved" "https://registry.npmjs.org/marked/-/marked-1.1.1.tgz"
"version" "1.1.1"
Expand Down Expand Up @@ -4956,11 +4931,6 @@
"resolved" "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz"
"version" "0.0.8"

"nan@^2.12.1":
"integrity" "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
"resolved" "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz"
"version" "2.14.1"

"nanoid@^1.0.7":
"integrity" "sha512-4ug4BsuHxiVHoRUe1ud6rUFT3WUMmjXt1W0quL0CviZQANdan7D8kqN5/maw53hmAApY/jfzMRkC57BNNs60ZQ=="
"resolved" "https://registry.npmjs.org/nanoid/-/nanoid-1.3.4.tgz"
Expand Down Expand Up @@ -7000,7 +6970,7 @@
"debug" "^3.1.0"
"proxy-agent" "2"

"superagent@^3.8.1":
"superagent@^3.8.1", "superagent@>= 0.15.4 || 1 || 2 || 3":
"integrity" "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA=="
"resolved" "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz"
"version" "3.8.3"
Expand Down Expand Up @@ -7274,23 +7244,7 @@
dependencies:
"tsutils" "^2.27.2 <2.29.0"

"tslint@5.4.3":
"integrity" "sha1-dhyEArgONHt3M6BDkKdXslNYBGc="
"resolved" "https://registry.npmjs.org/tslint/-/tslint-5.4.3.tgz"
"version" "5.4.3"
dependencies:
"babel-code-frame" "^6.22.0"
"colors" "^1.1.2"
"commander" "^2.9.0"
"diff" "^3.2.0"
"glob" "^7.1.1"
"minimatch" "^3.0.4"
"resolve" "^1.3.2"
"semver" "^5.3.0"
"tslib" "^1.7.1"
"tsutils" "^2.3.0"

"tslint@6.1.3":
"tslint@^5.1.0", "tslint@6.1.3":
"integrity" "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg=="
"resolved" "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz"
"version" "6.1.3"
Expand All @@ -7309,6 +7263,22 @@
"tslib" "^1.13.0"
"tsutils" "^2.29.0"

"tslint@5.4.3":
"integrity" "sha1-dhyEArgONHt3M6BDkKdXslNYBGc="
"resolved" "https://registry.npmjs.org/tslint/-/tslint-5.4.3.tgz"
"version" "5.4.3"
dependencies:
"babel-code-frame" "^6.22.0"
"colors" "^1.1.2"
"commander" "^2.9.0"
"diff" "^3.2.0"
"glob" "^7.1.1"
"minimatch" "^3.0.4"
"resolve" "^1.3.2"
"semver" "^5.3.0"
"tslib" "^1.7.1"
"tsutils" "^2.3.0"

"tsutils@^2.27.2 <2.29.0":
"integrity" "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA=="
"resolved" "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz"
Expand Down Expand Up @@ -7372,16 +7342,16 @@
"resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz"
"version" "0.8.1"

"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":
"integrity" "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw=="
"resolved" "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz"
"version" "3.9.7"

"typescript@~4.0.2":
"integrity" "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ=="
"resolved" "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz"
"version" "4.0.2"

"typescript@3.9.7":
"integrity" "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw=="
"resolved" "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz"
"version" "3.9.7"

"uglify-js@^3.1.4":
"integrity" "sha512-Lh00i69Uf6G74mvYpHCI9KVVXLcHW/xu79YTvH7Mkc9zyKUeSPz0owW0dguj0Scavns3ZOh3wY63J0Zb97Za2g=="
"resolved" "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.3.tgz"
Expand Down

0 comments on commit 6521671

Please sign in to comment.