Optimize performance of ShadowGenerator.Parse

Background

ShadowGenerator.Parse called scene.getMeshesById, which is O(n) in time, for each mesh id in parsedShadowGenerator.renderList, makes the loop O(m*n) in time, where n is the count of meshes in scene, m is the count of items in renderList.

And profiler shows there is a perf bottleneck in call to getMeshesById

Proposal

Use a set of id for efficient matching, should be O(m) in space, and O(n) in time.

diff --git a/packages/dev/core/src/Lights/Shadows/shadowGenerator.ts b/packages/dev/core/src/Lights/Shadows/shadowGenerator.ts
index 34eb5b4c65..7ad0124070 100644
--- a/packages/dev/core/src/Lights/Shadows/shadowGenerator.ts
+++ b/packages/dev/core/src/Lights/Shadows/shadowGenerator.ts
@@ -2155,16 +2155,17 @@ export class ShadowGenerator implements IShadowGenerator {
         const shadowGenerator = constr ? constr(parsedShadowGenerator.mapSize, light, camera) : new ShadowGenerator(parsedShadowGenerator.mapSize, light, undefined, camera);
         const shadowMap = shadowGenerator.getShadowMap();
 
-        for (let meshIndex = 0; meshIndex < parsedShadowGenerator.renderList.length; meshIndex++) {
-            const meshes = scene.getMeshesById(parsedShadowGenerator.renderList[meshIndex]);
+        if (parsedShadowGenerator.renderList.length && shadowMap) {
+            const renderSet = new Set<string>(parsedShadowGenerator.renderList);
+            let renderList = shadowMap.renderList;
+            if (!renderList) {
+                renderList = shadowMap.renderList = [];
+            }
+            const meshes = scene.meshes;
             for (const mesh of meshes) {
-                if (!shadowMap) {
-                    continue;
-                }
-                if (!shadowMap.renderList) {
-                    shadowMap.renderList = [];
+                if (renderSet.has(mesh.id)) {
+                    renderList.push(mesh);
                 }
-                shadowMap.renderList.push(mesh);
             }
         }

3 Likes

I’m game!

Thanks a lot btw for all these tidbits of optimization! This is great

And a PR here:

And seems something wrong with CI, without detailed error again

@ryantrem and @AlitarSemiramis can you check if we could display the error somehow ?

Can you run npm run format:fix ?

Not sure how but you did the same:

fixed in your PR

1 Like

Oh, never noticed that, my local copy works fine, but after pasting to github “Edit”, it added a new line. Thank you for that.

1 Like

Thank YOU for your appreciated help!

nw I feel like I helped lol