Tackle the last of the low hanging fruit for memory allocations in the main game loop.
- Avoid calling string.Split twice in SprintFont.Measure. - Change ActorsInBox method of ActorMap and ScreenMap to avoid allocating and intermediate list. As a bonus this allows the sequence to be lazily consumed. Also avoid LINQ in these methods. - In FrozenUnderFog.TickRender, the method exits early if no players are visible so the attempt at lazy generation was not needed. - Unwrap a LINQ Any call in ClassicProductionQueue.Tick. - Merge some successive Where calls in ProximityCapturable into single predicates.
This commit is contained in:
@@ -85,7 +85,8 @@ namespace OpenRA.Graphics
|
||||
|
||||
public int2 Measure(string text)
|
||||
{
|
||||
return new int2((int)text.Split('\n').Max(s => s.Sum(a => glyphs[Pair.New(a, Color.White)].Advance)), text.Split('\n').Count()*size);
|
||||
var lines = text.Split('\n');
|
||||
return new int2((int)Math.Ceiling(lines.Max(s => s.Sum(a => glyphs[Pair.New(a, Color.White)].Advance))), lines.Length * size);
|
||||
}
|
||||
|
||||
Cache<Pair<char,Color>, GlyphInfo> glyphs;
|
||||
|
||||
@@ -189,21 +189,22 @@ namespace OpenRA.Traits
|
||||
var j1 = (top / info.BinSize).Clamp(0, rows - 1);
|
||||
var j2 = (bottom / info.BinSize).Clamp(0, rows - 1);
|
||||
|
||||
var actorsInBox = new List<Actor>();
|
||||
var actorsChecked = new HashSet<Actor>();
|
||||
for (var j = j1; j <= j2; j++)
|
||||
{
|
||||
for (var i = i1; i <= i2; i++)
|
||||
{
|
||||
foreach (var actor in actors[j * cols + i])
|
||||
{
|
||||
var c = actor.CenterPosition;
|
||||
if (actor.IsInWorld && left <= c.X && c.X <= right && top <= c.Y && c.Y <= bottom)
|
||||
actorsInBox.Add(actor);
|
||||
if (actor.IsInWorld && actorsChecked.Add(actor))
|
||||
{
|
||||
var c = actor.CenterPosition;
|
||||
if (left <= c.X && c.X <= right && top <= c.Y && c.Y <= bottom)
|
||||
yield return actor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return actorsInBox.Distinct();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,14 +153,15 @@ namespace OpenRA.Traits
|
||||
var top = (r.Top / info.BinSize).Clamp(0, rows - 1);
|
||||
var bottom = (r.Bottom / info.BinSize).Clamp(0, rows - 1);
|
||||
|
||||
var actorsInBox = new List<Actor>();
|
||||
var actorsChecked = new HashSet<Actor>();
|
||||
for (var j = top; j <= bottom; j++)
|
||||
for (var i = left; i <= right; i++)
|
||||
actorsInBox.AddRange(actors[j * cols + i]
|
||||
.Where(kv => kv.Key.IsInWorld && kv.Value.IntersectsWith(r))
|
||||
.Select(kv => kv.Key));
|
||||
|
||||
return actorsInBox.Distinct();
|
||||
foreach (var kvp in actors[j * cols + i])
|
||||
{
|
||||
var actor = kvp.Key;
|
||||
if (actor.IsInWorld && kvp.Value.IntersectsWith(r) && actorsChecked.Add(actor))
|
||||
yield return actor;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<FrozenActor> FrozenActorsInBox(Player p, int2 a, int2 b)
|
||||
|
||||
Reference in New Issue
Block a user