Avoid per-frame delegate allocation in render-data lookups#94
Open
FMsongX2 wants to merge 1 commit into
Open
Conversation
ff37700 to
3ed60af
Compare
8d7e5b6 to
09f5d44
Compare
09f5d44 to
3ed60af
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces capturing-lambda
Array.FindIndexcalls on the per-frame render path with allocation-freeforloops, removing aPredicate<T>delegate allocation on every call. No behavior change.Problem
CubismRenderController.OnDynamicDrawableData— invoked fromCubismModel.Update()every frame — locates the renderer for each drawable with:It runs in three loops over all drawables, once per drawable before any dirty check —
3 × drawableCounttimes per frame. The lambda captures the loop variabledataIndex, so the compiler cannot cache it as a static delegate (only non-capturing lambdas are cached); aPredicate<T>is allocated on every call.CubismRenderingInterceptController.TryDrawhas the same pattern, capturingcurrentCamera.Changes
OnDynamicDrawableData: the three loops share one allocation-freeIndexOfDrawablehelper (a plainforloop) instead of the capturingArray.FindIndex.TryDraw: the capturingArray.FindIndexover_cameraDrawStatusis inlined as aforloop.Why this is safe
Functionally identical to
Array.FindIndex: it returns the first index whoseDrawable.UnmanagedIndexmatchesdataIndex(or the first entry whoseCameramatches, forTryDraw), or-1when none matches; the existing< 0handling is unchanged. The lookup is still resolved byDrawable.UnmanagedIndexexactly as before. No public API or behavior change.