Skip to content

VoiceTypeAssetLookup Optimisations - #707

Draft
kieranknowles1 wants to merge 19 commits into
Mutagen-Modding:devfrom
kieranknowles1:voice-fast-optimised
Draft

kieranknowles1 wants to merge 19 commits into
Mutagen-Modding:devfrom
kieranknowles1:voice-fast-optimised

Conversation

@kieranknowles1

Copy link
Copy Markdown
Contributor

Significant optimizations to VoiceTypeAssetLookup, resulting in a nearly 10x speedup when running against Skyrim.esm

Notable changes:

  • Add lookup of voice -> speakers for GetIsVoiceType conditions.
  • Remove unscoped resolve when running GetIsVoiceType against a form list.
  • Dedicated VoiceContainer.Invert function.
  • Avoid duplicate work during VoiceContainerExtensions.MergeInsert on an or block.
  • Use usage cache for scene responses

Includes fixes for voice container intersections that lose all speakers and aliases having conditions plus the unique actor fill type which both caused false positives, which will be extracted into their own PR.

Built on top of #697

Benchmarks, run with Skyrim.esm active and no other plugins.

Baseline

Method Mean Error StdDev Gen0 Gen1 Gen2 Allocated
Prep 687,873.293 us 884.0426 us 826.9340 us 48000.0000 7000.0000 - 816159.83 KB
GetIsId 2.877 us 0.0029 us 0.0024 us 0.3700 0.0038 - 6.05 KB
GetIsVoiceType 123.191 us 0.1562 us 0.1461 us 5.1270 0.7324 - 86.04 KB
GetIsVoiceTypeList 5,934.585 us 5.7906 us 5.1332 us 109.3750 7.8125 - 1935.76 KB
GetIsAliasRef 4.861 us 0.0055 us 0.0048 us 0.3891 - - 6.43 KB
GetInFaction 244.219 us 0.6291 us 0.5885 us 37.1094 9.7656 - 607.96 KB
GetIsClass 13.205 us 0.0140 us 0.0131 us 1.8311 0.0610 - 30.06 KB
HasKeyword 9.285 us 0.0123 us 0.0109 us 0.9460 0.0153 - 15.68 KB
GetIsRace 761.022 us 1.4777 us 1.2339 us 107.4219 38.0859 - 1759.41 KB
GetIsSex 1,907.222 us 10.3582 us 8.6495 us 195.3125 85.9375 11.7188 3480.56 KB
IsInList 12.289 us 0.0554 us 0.0491 us 1.1292 0.0153 - 18.6 KB
IsChild 19.461 us 0.0230 us 0.0204 us 2.2583 0.0610 - 36.96 KB
NonFilteringCondition 9.513 us 0.0095 us 0.0079 us 0.4425 - - 7.29 KB
InvertedCondition 1,067.862 us 1.2497 us 1.1078 us 183.5938 78.1250 - 3007.52 KB
SceneResponse 10.205 us 0.0193 us 0.0181 us 0.3357 - - 5.55 KB
GetAllSpeakers 10,221,645.860 us 56,655.5368 us 14,713.2630 us 1033000.0000 451000.0000 - 17149538.31 KB
GetAllPaths 9,532,661.220 us 172,753.1566 us 44,863.4463 us 1018000.0000 418000.0000 - 16827751.53 KB

Final

Method Mean Error StdDev Gen0 Gen1 Gen2 Allocated
Prep 429,702.377 us 1,315.5164 us 1,098.5158 us 29000.0000 5000.0000 - 485437.54 KB
GetIsId 2.477 us 0.0027 us 0.0023 us 0.2480 - - 4.06 KB
GetIsVoiceType 32.129 us 0.0607 us 0.0538 us 5.0049 0.5493 - 82.48 KB
GetIsVoiceTypeList 406.839 us 0.4983 us 0.4417 us 22.4609 6.3477 3.4180 438.29 KB
GetIsAliasRef 4.385 us 0.0051 us 0.0048 us 0.2594 - - 4.34 KB
GetInFaction 111.406 us 0.2713 us 0.2538 us 11.3525 2.1973 - 186.98 KB
GetIsClass 8.427 us 0.0083 us 0.0074 us 0.7019 - - 11.57 KB
HasKeyword 7.086 us 0.0059 us 0.0049 us 0.4044 - - 6.66 KB
GetIsRace 329.743 us 1.4947 us 1.3982 us 30.7617 9.2773 - 508.65 KB
GetIsSex 800.213 us 1.9596 us 1.8330 us 56.6406 23.4375 3.9063 998.57 KB
IsInList 9.148 us 0.0098 us 0.0086 us 0.4120 - - 6.74 KB
IsChild 13.031 us 0.0105 us 0.0093 us 0.9155 0.0153 - 15.14 KB
NonFilteringCondition 9.052 us 0.0065 us 0.0061 us 0.3052 - - 5 KB
InvertedCondition 82.308 us 0.1407 us 0.1316 us 17.5781 4.3945 - 288.66 KB
SceneResponse 11.366 us 0.0138 us 0.0122 us 0.3662 - - 6.08 KB
GetAllSpeakers 1,355,111.600 us 20,700.3245 us 5,375.8085 us 117000.0000 40000.0000 - 2004564.71 KB
GetAllPaths 1,079,140.720 us 9,834.9540 us 2,554.1063 us 87000.0000 26000.0000 - 1436868.8 KB

Original was incorrect, second case did not include the dummy speaker.
Tighten to enforce behaviour around inverting (see PR Mutagen-Modding#697 comment)
Split sets of faction NPCs into statically defined members and potential
members.
Costs a few ms on prep, but greatly accelerates GetIsVoiceType searches.
Replace unscoped resolve in `GetIsVoiceType` form list check with
hashset. Probably intended to check the entry was a voice type but never
enforced this.
Slight reduction in allocations across the board.
Reduce usage of `ToDictionary` in condition handling. Slight speedup to
these conditions.
Significantly improves invert performance, 2x whole load order speed
from this alone.
The voiceContainers.Any() check meant evaluating the container creation
twice for each OR block

Significant improvements across the board from this.
Use usage cache for scene responses. Saves memory at the cost of minimal
performance loss in scenes.
Represent universal set as null instead. Getting into micro
optimisations here, but still gives a small speedup and decent reduction
in allocations.

This branch has not been deployed

No deployments
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