-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathengine.patch
More file actions
81 lines (79 loc) · 4.02 KB
/
Copy pathengine.patch
File metadata and controls
81 lines (79 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
--- src/MedWNetworkSim.App/Services/NetworkSimulationEngine.cs
+++ src/MedWNetworkSim.App/Services/NetworkSimulationEngine.cs
@@ -40,9 +40,14 @@
var hasRecipeDependencies = HasStaticRecipeDependencies(network);
- var definitionsByTraffic = network.TrafficTypes
- .Where(definition => !string.IsNullOrWhiteSpace(definition.Name))
- .GroupBy(definition => definition.Name, Comparer)
- .ToDictionary(group => group.Key, group => group.First(), Comparer);
+ // Bolt: Replaced LINQ Where, GroupBy, and ToDictionary with a manual loop to prevent IGrouping
+ // allocations and excessive delegate overhead, keeping the Dictionary un-sized to avoid memory over-allocation.
+ var definitionsByTraffic = new Dictionary<string, TrafficTypeDefinition>(Comparer);
+ foreach (var definition in network.TrafficTypes)
+ {
+ if (!string.IsNullOrWhiteSpace(definition.Name))
+ {
+ definitionsByTraffic.TryAdd(definition.Name, definition);
+ }
+ }
var contexts = MixedRoutingAllocator.BuildStaticContexts(network, applyLocalAllocations: !hasRecipeDependencies).ToList();
// Bolt: Replaced LINQ .ToDictionary() with manual foreach to avoid enumerator and delegate allocations
@@ -338,9 +343,11 @@
private NetworkModel OrderNetworkForLayerProcessing(NetworkModel network)
{
- var order = layerResolver.GetSimulationOrder(network)
- .Select((layer, index) => new { layer.Id, index })
- .ToDictionary(item => item.Id, item => item.index);
+ var simulationOrder = layerResolver.GetSimulationOrder(network);
+ // Bolt: Replaced LINQ Select and ToDictionary with a manual loop to prevent anonymous object and enumerator allocations.
+ var order = new Dictionary<Guid, int>(simulationOrder.Count);
+ for (int i = 0; i < simulationOrder.Count; i++)
+ {
+ order[simulationOrder[i].Id] = i;
+ }
return new NetworkModel
@@ -758,21 +765,22 @@
private static Dictionary<string, double> SummarizeLandedUnitCosts(IEnumerable<RouteAllocation> allocations)
{
- return allocations
- .GroupBy(allocation => allocation.ConsumerNodeId, Comparer)
- .ToDictionary(
- group => group.Key,
- group =>
- {
- // Bolt: Accumulate quantity and total cost in a single loop to avoid multiple O(N) LINQ enumerations and delegate allocations
- var quantity = 0d;
- var totalCost = 0d;
- foreach (var allocation in group)
- {
- quantity += allocation.Quantity;
- totalCost += allocation.DeliveredCostPerUnit * allocation.Quantity;
- }
-
- return quantity > Epsilon ? totalCost / quantity : 0d;
- },
- Comparer);
+ // Bolt: Replaced LINQ GroupBy and ToDictionary with a single-pass Dictionary aggregation
+ // to eliminate IGrouping allocations, enumerator closures, and excessive delegate overhead.
+ var totals = new Dictionary<string, (double Quantity, double TotalCost)>(Comparer);
+ foreach (var allocation in allocations)
+ {
+ var addCost = allocation.DeliveredCostPerUnit * allocation.Quantity;
+ if (totals.TryGetValue(allocation.ConsumerNodeId, out var current))
+ {
+ totals[allocation.ConsumerNodeId] = (current.Quantity + allocation.Quantity, current.TotalCost + addCost);
+ }
+ else
+ {
+ totals[allocation.ConsumerNodeId] = (allocation.Quantity, addCost);
+ }
+ }
+
+ var result = new Dictionary<string, double>(totals.Count, Comparer);
+ foreach (var pair in totals)
+ {
+ result.Add(pair.Key, pair.Value.Quantity > Epsilon ? pair.Value.TotalCost / pair.Value.Quantity : 0d);
+ }
+
+ return result;
}