Faust SetControls: remove per-call allocation #2

Open
aqua wants to merge 1 commit from aqua/setcontrols-no-alloc into main
Member

Marshal.Copy([value], 0, zone, 1) allocated a float[1] (32 B) per control, and the foreach over IReadOnlyDictionary boxed an enumerator (56 B) per call. Now the float bits are written straight to the zone with Marshal.WriteInt32, and a Dictionary<string,float> argument is iterated with its struct enumerator (interface fallback kept for other callers).

Evidence (Linux, .NET 10.0.14, Faust 2.90.20, 10000 blocks x 512 frames, 2 controls set per block, dx7/algorithm-8-bright-pair and advanced/additive-pad):

thread alloc delta bytes/block gc0/1/2
main 1,200,000 120.00 0/0/0
this branch 0 0.00 0/0/0

Mean block time is unchanged (0.078 ms / 0.133 ms). A 3 s render of bright-pair is byte-identical before and after (peak 0.1504, RMS 0.02093), so the zone write is bit-exact.

Not covered: no new unit test (the allocation check lives in the out-of-tree smoke harness); Linux only. Not merged.

🤖 Generated with Claude Code

`Marshal.Copy([value], 0, zone, 1)` allocated a `float[1]` (32 B) per control, and the `foreach` over `IReadOnlyDictionary` boxed an enumerator (56 B) per call. Now the float bits are written straight to the zone with `Marshal.WriteInt32`, and a `Dictionary<string,float>` argument is iterated with its struct enumerator (interface fallback kept for other callers). **Evidence (Linux, .NET 10.0.14, Faust 2.90.20, 10000 blocks x 512 frames, 2 controls set per block, `dx7/algorithm-8-bright-pair` and `advanced/additive-pad`):** | | thread alloc delta | bytes/block | gc0/1/2 | |---|---|---|---| | main | 1,200,000 | 120.00 | 0/0/0 | | this branch | 0 | 0.00 | 0/0/0 | Mean block time is unchanged (0.078 ms / 0.133 ms). A 3 s render of bright-pair is byte-identical before and after (peak 0.1504, RMS 0.02093), so the zone write is bit-exact. Not covered: no new unit test (the allocation check lives in the out-of-tree smoke harness); Linux only. Not merged. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Marshal.Copy([value], ...) allocated a float[1] per control and the
IReadOnlyDictionary foreach boxed an enumerator per call. Write the float
bits straight to the zone and use Dictionary's struct enumerator when the
caller passes one. 10000-block smoke on a 2-control patch: 120 B/block -> 0.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin aqua/setcontrols-no-alloc:aqua/setcontrols-no-alloc
git switch aqua/setcontrols-no-alloc

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff aqua/setcontrols-no-alloc
git switch aqua/setcontrols-no-alloc
git rebase main
git switch main
git merge --ff-only aqua/setcontrols-no-alloc
git switch aqua/setcontrols-no-alloc
git rebase main
git switch main
git merge --no-ff aqua/setcontrols-no-alloc
git switch main
git merge --squash aqua/setcontrols-no-alloc
git switch main
git merge --ff-only aqua/setcontrols-no-alloc
git switch main
git merge aqua/setcontrols-no-alloc
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/AquaSynth!2
No description provided.