Reduce allocations in the main game loop.

- Cache the shroud projection even for flat maps to avoid allocating single element arrays.
- Avoid LINQ in shroud and map projection queries to avoid enumerator allocations.
- Avoid LINQ in calculation of sync values.
- Cache enumerables in ProductionQueue.
- Cache delegate in HackyAI.
This commit is contained in:
RoosterDragon
2015-08-12 23:45:11 +01:00
parent 1e817fad76
commit d415d3ba4e
7 changed files with 105 additions and 65 deletions

View File

@@ -40,7 +40,17 @@ namespace OpenRA.Mods.Common.Traits
public class RepairableBuilding : UpgradableTrait<RepairableBuildingInfo>, ITick
{
[Sync]
public int RepairersHash { get { return Repairers.Aggregate(0, (code, player) => code ^ Sync.HashPlayer(player)); } }
public int RepairersHash
{
get
{
var hash = 0;
foreach (var player in Repairers)
hash ^= Sync.HashPlayer(player);
return hash;
}
}
public readonly List<Player> Repairers = new List<Player>();
readonly Health health;
@@ -94,7 +104,9 @@ namespace OpenRA.Mods.Common.Traits
Repairers.RemoveAll(isNotActiveAlly);
// If after the previous operation there's no repairers left, stop
if (!Repairers.Any()) return;
if (Repairers.Count == 0)
return;
var buildingValue = self.GetSellValue();
// The cost is the same regardless of the amount of people repairing

View File

@@ -70,6 +70,7 @@ namespace OpenRA.Mods.Common.Traits
readonly HarvesterInfo info;
readonly Mobile mobile;
Dictionary<ResourceTypeInfo, int> contents = new Dictionary<ResourceTypeInfo, int>();
bool idleSmart = true;
[Sync] public Actor OwnerLinkedProc = null;
[Sync] public Actor LastLinkedProc = null;
@@ -77,8 +78,17 @@ namespace OpenRA.Mods.Common.Traits
[Sync] int currentUnloadTicks;
public CPos? LastHarvestedCell = null;
public CPos? LastOrderLocation = null;
[Sync] public int ContentValue { get { return contents.Sum(c => c.Key.ValuePerUnit * c.Value); } }
bool idleSmart = true;
[Sync]
public int ContentValue
{
get
{
var value = 0;
foreach (var c in contents)
value += c.Key.ValuePerUnit * c.Value;
return value;
}
}
public Harvester(Actor self, HarvesterInfo info)
{

View File

@@ -58,7 +58,16 @@ namespace OpenRA.Mods.Common.Traits
public ReadOnlyList<MissionObjective> Objectives;
[Sync]
public int ObjectivesHash { get { return Objectives.Aggregate(0, (code, objective) => code ^ Sync.Hash(objective.State)); } }
public int ObjectivesHash
{
get
{
var hash = 0;
foreach (var objective in objectives)
hash ^= Sync.Hash(objective.State);
return hash;
}
}
// This property is used as a flag in 'Cooperative' games to mark that the player has completed all his objectives.
// The player's WinState is only updated when his allies have all completed their objective as well.

View File

@@ -68,15 +68,17 @@ namespace OpenRA.Mods.Common.Traits
public readonly ProductionQueueInfo Info;
readonly Actor self;
// A list of things we could possibly build
readonly Dictionary<ActorInfo, ProductionState> produceable = new Dictionary<ActorInfo, ProductionState>();
readonly List<ProductionItem> queue = new List<ProductionItem>();
readonly IEnumerable<ActorInfo> allProduceables;
readonly IEnumerable<ActorInfo> buildableProduceables;
// Will change if the owner changes
PowerManager playerPower;
PlayerResources playerResources;
protected DeveloperMode developerMode;
// A list of things we could possibly build
Dictionary<ActorInfo, ProductionState> produceable;
List<ProductionItem> queue = new List<ProductionItem>();
public Actor Actor { get { return self; } }
[Sync] public int QueueLength { get { return queue.Count; } }
@@ -101,6 +103,8 @@ namespace OpenRA.Mods.Common.Traits
Enabled = !info.Factions.Any() || info.Factions.Contains(Faction);
CacheProduceables(playerActor);
allProduceables = produceable.Where(a => a.Value.Buildable || a.Value.Visible).Select(a => a.Key);
buildableProduceables = produceable.Where(a => a.Value.Buildable).Select(a => a.Key);
}
void ClearQueue()
@@ -143,7 +147,7 @@ namespace OpenRA.Mods.Common.Traits
void CacheProduceables(Actor playerActor)
{
produceable = new Dictionary<ActorInfo, ProductionState>();
produceable.Clear();
if (!Enabled)
return;
@@ -200,9 +204,9 @@ namespace OpenRA.Mods.Common.Traits
public virtual IEnumerable<ActorInfo> AllItems()
{
if (self.World.AllowDevCommands && developerMode.AllTech)
return produceable.Select(a => a.Key);
return produceable.Keys;
return produceable.Where(a => a.Value.Buildable || a.Value.Visible).Select(a => a.Key);
return allProduceables;
}
public virtual IEnumerable<ActorInfo> BuildableItems()
@@ -210,9 +214,9 @@ namespace OpenRA.Mods.Common.Traits
if (!Enabled)
return Enumerable.Empty<ActorInfo>();
if (self.World.AllowDevCommands && developerMode.AllTech)
return produceable.Select(a => a.Key);
return produceable.Keys;
return produceable.Where(a => a.Value.Buildable).Select(a => a.Key);
return buildableProduceables;
}
public bool CanBuild(ActorInfo actor)