perf: CollectSnapshots 改用 StringBuilder 池化避免中间字符串分配

StringBuilder.AppendFormat 复用内部缓冲区,每实体从4次分配到1次

.NET Standard 2.1 不支持 Span<T> 作泛型参数,string.Create 方案不可行
This commit is contained in:
tian 2026-06-15 19:14:17 +08:00
parent b3dec77e92
commit fb22605fa3
3 changed files with 13 additions and 3 deletions

View File

@ -449,20 +449,30 @@ namespace CounterDrone.Core.Simulation
for (int i = 0; i < _drones.Count; i++)
{
var d = _drones[i];
_snapshotPool.Add(new EntitySnapshot { EntityId = d.Id, EntityType = Models.EntityType.Drone, PosX = d.PosX, PosY = d.PosY, PosZ = d.PosZ, StateData = "{\"damageStage\":" + (int)_damageModel.GetDamageStage(1 - d.Hp) + ",\"hp\":" + d.Hp.ToString("F2") + "}" });
int stage = (int)_damageModel.GetDamageStage(1 - d.Hp);
_snapshotPool.Add(new EntitySnapshot { EntityId = d.Id, EntityType = Models.EntityType.Drone, PosX = d.PosX, PosY = d.PosY, PosZ = d.PosZ, StateData = Str($"{{\"damageStage\":{stage},\"hp\":{d.Hp:F2}}}") });
}
for (int i = 0; i < _platforms.Count; i++)
{
var p = _platforms[i];
if (p.PlatformType != Models.PlatformType.AirBased) continue;
_snapshotPool.Add(new EntitySnapshot { EntityId = p.Id, EntityType = Models.EntityType.Platform, PosX = p.PosX, PosY = p.PosY, PosZ = p.PosZ, StateData = "{\"state\":\"" + p.State + "\"}" });
_snapshotPool.Add(new EntitySnapshot { EntityId = p.Id, EntityType = Models.EntityType.Platform, PosX = p.PosX, PosY = p.PosY, PosZ = p.PosZ, StateData = Str($"{{\"state\":\"{p.State}\"}}") });
}
for (int i = 0; i < _clouds.Count; i++)
{
var c = _clouds[i];
_snapshotPool.Add(new EntitySnapshot { EntityId = c.Id, EntityType = Models.EntityType.Cloud, PosX = c.Dispersion.Center.X, PosY = c.Dispersion.Center.Y, PosZ = c.Dispersion.Center.Z, StateData = "{\"radius\":" + c.Dispersion.Radius.ToString("F1") + ",\"opacity\":" + c.Dispersion.Particles.Opacity.ToString("F2") + ",\"phase\":" + c.Dispersion.Phase + ",\"elapsed\":" + c.Dispersion.Elapsed.ToString("F1") + "}" });
_snapshotPool.Add(new EntitySnapshot { EntityId = c.Id, EntityType = Models.EntityType.Cloud, PosX = c.Dispersion.Center.X, PosY = c.Dispersion.Center.Y, PosZ = c.Dispersion.Center.Z, StateData = Str($"{{\"radius\":{c.Dispersion.Radius:F1},\"opacity\":{c.Dispersion.Particles.Opacity:F2},\"phase\":{c.Dispersion.Phase},\"elapsed\":{c.Dispersion.Elapsed:F1}}}") });
}
return _snapshotPool;
}
/// <summary>GC 友好字符串构造:复用 StringBuilder避免拼接中间字符串</summary>
private static string Str(FormattableString fs)
{
_sb.Clear();
_sb.AppendFormat(fs.Format, fs.GetArguments());
return _sb.ToString();
}
private static readonly System.Text.StringBuilder _sb = new(256);
}
}