From 42a8ed31e34b7ae51ce0bb1c2a94c8bef59ab8e3 Mon Sep 17 00:00:00 2001 From: Artur Androsovych Date: Wed, 13 Mar 2024 02:33:18 +0200 Subject: [PATCH] perf(store): improve compliant prop getter (#2106) This commit enhances the `compliantPropGetter` function's implementation. The prop getter is heavily utilized in NGXS. I noticed that the function unnecessarily copies `paths`. It now returns a function that accepts an object as a parameter and attempts to select a property deeply. We've replaced the use of `reduce` with a single for-loop, making it simpler. Though it doesn't significantly impact size, there's only a minor difference in production bundle size. Regarding performance, I checked the `perf.link` service and got the following results: - Old compliant prop getter: 120,410 ops/s - New compliant prop getter: 220,480 ops/s I generated a deeply nested object and set my CPU slowdown to 6x. The new implementation is only 30% faster, but it's reasonable to have a slightly faster implementation if possible. At least it's not causing any negative impact. --- packages/store/src/internal/internals.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/store/src/internal/internals.ts b/packages/store/src/internal/internals.ts index fc9b0c293..e85c7be0c 100644 --- a/packages/store/src/internal/internals.ts +++ b/packages/store/src/internal/internals.ts @@ -44,8 +44,13 @@ export interface StatesAndDefaults { * @ignore */ function compliantPropGetter(paths: string[]): (x: any) => any { - const copyOfPaths = paths.slice(); - return obj => copyOfPaths.reduce((acc: any, part: string) => acc && acc[part], obj); + return obj => { + for (let i = 0; i < paths.length; i++) { + if (!obj) return undefined; + obj = obj[paths[i]]; + } + return obj; + }; } /**