可能的性能优化

This commit is contained in:
2026-03-20 18:48:11 +08:00
parent 41e38311f0
commit 27d57a28a9
7 changed files with 90 additions and 67 deletions
@@ -18,11 +18,15 @@ namespace OCES.Audio
readonly Dictionary<uint, int> m_clipConcurrentCount = new();
readonly List<ActiveSound> m_activeSounds = new();
// 复用列表,避免 TryPlay 每帧分配临时 List(原 LINQ .Where().ToList()
readonly List<ActiveSound> m_tempSameObject = new();
readonly List<ActiveSound> m_tempSameGroup = new();
readonly List<ActiveSound> m_tempLowerPriority = new();
AudioGroupConfig m_groupConfig;
AudioMixerGroup m_sfxGroup;
AudioMixerGroup m_musicGroup;
AudioMixerGroup m_voiceGroup;
AudioMixerGroup m_ambienceGroup;
AudioSourcePool m_pool;
AudioContainerSelector m_containerSelector;
PitchStepManager m_pitchStepManager;
@@ -60,8 +64,6 @@ namespace OCES.Audio
AudioMixerGroup[] sfx = Find("Master/SFX");
if (sfx.Length > 0) this.m_sfxGroup = sfx[0];
AudioMixerGroup[] ambience = Find("Master/SFX/Ambience");
if (ambience.Length > 0) this.m_ambienceGroup = ambience[0];
AudioMixerGroup[] voice = Find("Master/Voice");
if (voice.Length > 0) this.m_voiceGroup = voice[0];
return;
@@ -87,15 +89,20 @@ namespace OCES.Audio
// 第二层:单 AudioObject/Clip 并发控制
if (audioObject.ThrottleCount != 0)
{ // TODO 这里和下面的组控制,每次都会分配新List,可以考虑做成成员变量,每次用完clear
// TODO Linq表达式好用但是GC性能差。如果性能有问题可以考虑换成普通表达
List<ActiveSound> sameObject = this.m_activeSounds
.Where(a => a.AudioObject.Id == audioObject.Id)
.ToList();
{
this.m_tempSameObject.Clear();
foreach (ActiveSound activeSound in this.m_activeSounds)
{
if (activeSound.AudioObject.Id == audioObject.Id)
{
this.m_tempSameObject.Add(activeSound);
}
}
if (sameObject.Count >= audioObject.ThrottleCount &&
!TryKill(sameObject, audioObject.KillMode, $"[Object] {audioObject.Name[0]}"))
if (this.m_tempSameObject.Count >= audioObject.ThrottleCount &&
!TryKill(this.m_tempSameObject, audioObject.KillMode, $"[Object] {audioObject.Name[0]}"))
return;
}
// 第三层:Group 并发控制
@@ -105,18 +112,28 @@ namespace OCES.Audio
groupConfig = this.m_groupConfig.QueryById(1);
Debug.Log($"未找到{audioObject.Id}对应的组文件,已使用默认配置组1。");
}
List<ActiveSound> sameGroup = this.m_activeSounds
.Where(a => a.AudioObject.Group == audioObject.Group)
.ToList();
if (sameGroup.Count >= groupConfig.GroupThrottleCount)
this.m_tempSameGroup.Clear();
foreach (ActiveSound activeSound in this.m_activeSounds)
{
List<ActiveSound> lowerPriority = sameGroup
.Where(a => a.AudioObject.Priority > audioObject.Priority)
.ToList();
if (activeSound.AudioObject.Group == audioObject.Group)
{
this.m_tempSameGroup.Add(activeSound);
}
}
if (this.m_tempSameGroup.Count >= groupConfig.GroupThrottleCount)
{
this.m_tempLowerPriority.Clear();
foreach (ActiveSound activeSound in this.m_tempSameGroup)
{
if (activeSound.AudioObject.Priority > audioObject.Priority)
{
this.m_tempLowerPriority.Add(activeSound);
}
}
List<ActiveSound> killCandidates = lowerPriority.Count > 0 ? lowerPriority : sameGroup;
KillMode killMode = lowerPriority.Count > 0 ? groupConfig.KillMode : audioObject.KillMode;
List<ActiveSound> killCandidates = this.m_tempLowerPriority.Count > 0 ? this.m_tempLowerPriority : this.m_tempSameGroup;
KillMode killMode = this.m_tempLowerPriority.Count > 0 ? groupConfig.KillMode : audioObject.KillMode;
if (!TryKill(killCandidates, killMode, $"[Group] {audioObject.Name[0]}"))
return;
@@ -125,11 +142,16 @@ namespace OCES.Audio
// 第四层:全局并发控制
if (this.m_activeSounds.Count >= k_maxGlobalConcurrent)
{
List<ActiveSound> lowerPriority = this.m_activeSounds
.Where(a => a.AudioObject.Priority > audioObject.Priority)
.ToList();
this.m_tempLowerPriority.Clear();
foreach (ActiveSound activeSound in this.m_activeSounds)
{
if (activeSound.AudioObject.Priority > audioObject.Priority)
{
this.m_tempLowerPriority.Add(activeSound);
}
}
if (lowerPriority.Count == 0 || !TryKill(lowerPriority, KillMode.Oldest, "[Global]"))
if (this.m_tempLowerPriority.Count == 0 || !TryKill(this.m_tempLowerPriority, KillMode.Oldest, "[Global]"))
return;
}