Skip to content

Avoid per-frame delegate allocation in render-data lookups#94

Open
FMsongX2 wants to merge 1 commit into
Live2D:developfrom
FMsongX2:fix/renderer-findindex-alloc
Open

Avoid per-frame delegate allocation in render-data lookups#94
FMsongX2 wants to merge 1 commit into
Live2D:developfrom
FMsongX2:fix/renderer-findindex-alloc

Conversation

@FMsongX2

@FMsongX2 FMsongX2 commented Jun 24, 2026

Copy link
Copy Markdown

Summary

Replaces capturing-lambda Array.FindIndex calls on the per-frame render path with allocation-free for loops, removing a Predicate<T> delegate allocation on every call. No behavior change.

Problem

CubismRenderController.OnDynamicDrawableData — invoked from CubismModel.Update() every frame — locates the renderer for each drawable with:

var rendererIndex = Array.FindIndex(renderers, cubismRenderer => cubismRenderer.Drawable.UnmanagedIndex == dataIndex);

It runs in three loops over all drawables, once per drawable before any dirty check — 3 × drawableCount times per frame. The lambda captures the loop variable dataIndex, so the compiler cannot cache it as a static delegate (only non-capturing lambdas are cached); a Predicate<T> is allocated on every call. CubismRenderingInterceptController.TryDraw has the same pattern, capturing currentCamera.

Changes

  • OnDynamicDrawableData: the three loops share one allocation-free IndexOfDrawable helper (a plain for loop) instead of the capturing Array.FindIndex.
  • TryDraw: the capturing Array.FindIndex over _cameraDrawStatus is inlined as a for loop.

Why this is safe

Functionally identical to Array.FindIndex: it returns the first index whose Drawable.UnmanagedIndex matches dataIndex (or the first entry whose Camera matches, for TryDraw), or -1 when none matches; the existing < 0 handling is unchanged. The lookup is still resolved by Drawable.UnmanagedIndex exactly as before. No public API or behavior change.

@FMsongX2 FMsongX2 force-pushed the fix/renderer-findindex-alloc branch from ff37700 to 3ed60af Compare June 25, 2026 00:15
@FMsongX2 FMsongX2 changed the title Replace Array.FindIndex with for loop to avoid closure allocation Avoid per-frame allocation and O(N²) search in render-data lookups Jun 25, 2026
@FMsongX2 FMsongX2 force-pushed the fix/renderer-findindex-alloc branch 2 times, most recently from 8d7e5b6 to 09f5d44 Compare June 25, 2026 15:27
@FMsongX2 FMsongX2 changed the title Avoid per-frame allocation and O(N²) search in render-data lookups Avoid per-frame delegate allocation in render-data lookups Jun 26, 2026
@FMsongX2 FMsongX2 force-pushed the fix/renderer-findindex-alloc branch from 09f5d44 to 3ed60af Compare June 26, 2026 12:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant