arkavo-org / arkavo-org/VRMMetalKit

Per-primitive morph active-set sort is O(m log m) every frame

Open
#218 0 comments 0 reactions 0 assignees View on GitHub
medium performance
Dominant language
Swift
Stars
6
Forks
2
Avg merge
18h 51m
Merged PRs (30d)
26

Description

## Summary
`buildActiveSet(weights:)` allocates a temporary array of all morph candidates, sorts them by `abs(weight)` descending, and takes the top N. This happens once per primitive, every frame.

## Impact
- O(m log m) sort where m = morph count per primitive.
- Temporary array allocation per primitive per frame.
- For models with many morph targets per primitive, this dominates CPU frame time.

## Location
- `Sources/VRMMetalKit/Animation/VRMMorphTargets.swift:214–239`
- Called from `applyMorphsCompute` at `:310–390`

## Evidence
```swift
var candidates: [ActiveMorph] = []
// ... append all non-zero morphs ...
candidates.sort { abs($0.weight) > abs($1.weight) }
activeSet = Array(candidates.prefix(activeCount))
```

## Suggested Fix
Replace the full sort with a **fixed-size top-K selection** (e.g. top 8). Use a small fixed array on the stack and a linear scan instead of `sort()`. This changes complexity from O(m log m) to O(m) and eliminates the heap allocation.

Contributor guide

Open the contributing guide

Research direction

Start in Sources/VRMMetalKit/Animation/VRMMorphTargets.swift at buildActiveSet(weights:) lines 214–239, then inspect its caller applyMorphsCompute at lines 310–390. Replace the full candidate sort with the suggested fixed-size top-K selection while preserving the active-count behavior. Done means selecting the highest-absolute-weight morphs without the per-frame temporary array and O(m log m) sort.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
computer-graphics, performance
Issue type
Refactor
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
62/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.