Description:
Optimize PreserveCounts and only recalculate when needed.
Previously would recalculate preservecounts every Update call (~1 per frame), which isn't necessary
when there's no tick. Might be some room to tweak, like doing these updates only when preserves change.
Some measurements: This takes about 30ms versus the .25 ms with no preserve (then like .0002ms).
When the map is filled up with preserve, about 35ms and 9ms. With a handful of
cells, it's more like 0.8ms (before JIT optimizes most of it away).
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
@@ -1,4 +1,4 | |||||
|
1 | // <autogenerated /> |
|
1 | // <autogenerated /> |
|
2 | using System; |
|
2 | using System; |
|
3 | using System.Reflection; |
|
3 | using System.Reflection; |
|
4 | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] |
|
4 | // [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] |
@@ -164,6 +164,45 | |||||
|
164 | yield return this.cells[x - 1][y+1]; |
|
164 | yield return this.cells[x - 1][y+1]; |
|
165 | } |
|
165 | } |
|
166 | } |
|
166 | } |
|
|
167 | |||
|
|
168 | public System.Collections.Generic.IEnumerable<(int, int)> iterate_neighbor_cell_locations(int x, int y) | ||
|
|
169 | |||
|
|
170 | { | ||
|
|
171 | //iterates over neighbors (clockwise starting at noon/midnight) | ||
|
|
172 | if (inBounds(x, y + 1)) | ||
|
|
173 | { | ||
|
|
174 | yield return (x - 1, y); | ||
|
|
175 | } | ||
|
|
176 | if (inBounds(x + 1, y + 1)) | ||
|
|
177 | { | ||
|
|
178 | yield return (x + 1, y + 1); | ||
|
|
179 | } | ||
|
|
180 | if (inBounds(x + 1, y)) | ||
|
|
181 | { | ||
|
|
182 | yield return (x + 1, y); | ||
|
|
183 | } | ||
|
|
184 | if (inBounds(x + 1, y - 1)) | ||
|
|
185 | { | ||
|
|
186 | yield return (x + 1, y - 1); | ||
|
|
187 | } | ||
|
|
188 | if (inBounds(x, y - 1)) | ||
|
|
189 | { | ||
|
|
190 | yield return (x, y - 1); | ||
|
|
191 | } | ||
|
|
192 | if (inBounds(x - 1, y-1)) | ||
|
|
193 | { | ||
|
|
194 | yield return (x - 1, y-1); | ||
|
|
195 | } | ||
|
|
196 | if (inBounds(x - 1, y)) | ||
|
|
197 | { | ||
|
|
198 | yield return (x - 1, y); | ||
|
|
199 | } | ||
|
|
200 | if (inBounds(x - 1, y + 1)) | ||
|
|
201 | { | ||
|
|
202 | yield return (x - 1, y+1); | ||
|
|
203 | } | ||
|
|
204 | } | ||
|
|
205 | |||
|
167 |
|
206 | ||
|
168 | public System.Collections.Generic.IEnumerable<Cell> iterate_neighbors(int x, int y) |
|
207 | public System.Collections.Generic.IEnumerable<Cell> iterate_neighbors(int x, int y) |
|
169 | { |
|
208 | { |
@@ -1,4 +1,5 | |||||
|
1 | using System; |
|
1 | using System; |
|
|
2 | using System.Diagnostics; | ||
|
2 | using System.Linq; |
|
3 | using System.Linq; |
|
3 | using System.Collections.Generic; |
|
4 | using System.Collections.Generic; |
|
4 |
|
5 | ||
@@ -72,28 +73,6 | |||||
|
72 |
|
73 | ||
|
73 | // this.simulation.PreserveCells.Clear(); |
|
74 | // this.simulation.PreserveCells.Clear(); |
|
74 |
|
75 | ||
|
75 | var preserve_cells = new HashSet<isometricparkfna.CellMap.Cell>(); |
|
||
|
76 | var count = 0; |
|
||
|
77 |
|
|||
|
78 | foreach (ref readonly var entity in ReadEntities<PreserveComponent>()) { |
|
||
|
79 | ref readonly var areaComponent = ref GetComponent<AreaComponent>(entity); |
|
||
|
80 |
|
|||
|
81 | foreach (var square in areaComponent.squares) { |
|
||
|
82 | preserve_cells.Add(this.simulation.map.cells[(int)square.X][(int)square.Y]); |
|
||
|
83 | } |
|
||
|
84 | } |
|
||
|
85 |
|
|||
|
86 | for (int i = 0; i < this.simulation.PreserveCounts.GetLength(0); i++) { |
|
||
|
87 | for (int j = 0; j < this.simulation.PreserveCounts.GetLength(0); j++) { |
|
||
|
88 | count = 0; |
|
||
|
89 | foreach (var cell in this.simulation.map.iterate_neighbor_cells(i, j)) { |
|
||
|
90 | if (preserve_cells.Contains(cell)) { |
|
||
|
91 | count++; |
|
||
|
92 | } |
|
||
|
93 | } |
|
||
|
94 | this.simulation.PreserveCounts[i, j] = count; |
|
||
|
95 | } |
|
||
|
96 | } |
|
||
|
97 |
|
76 | ||
|
98 | foreach (ref readonly var entity in ReadEntities<BudgetLineComponent>()) |
|
77 | foreach (ref readonly var entity in ReadEntities<BudgetLineComponent>()) |
|
99 | { |
|
78 | { |
@@ -133,6 +112,62 | |||||
|
133 | } |
|
112 | } |
|
134 | for (int i = ticksToSend; i > 0; i--) |
|
113 | for (int i = ticksToSend; i > 0; i--) |
|
135 | { |
|
114 | { |
|
|
115 | |||
|
|
116 | #region calculate_preserve_cells | ||
|
|
117 | var preserve_cells = new HashSet<isometricparkfna.CellMap.Cell>(); | ||
|
|
118 | var preserve_cell_coordinates = new HashSet<(int, int)>(); | ||
|
|
119 | var count = 0; | ||
|
|
120 | |||
|
|
121 | Stopwatch iterPreserves = new Stopwatch(); | ||
|
|
122 | iterPreserves.Start(); | ||
|
|
123 | |||
|
|
124 | foreach (ref readonly var entity in ReadEntities<PreserveComponent>()) { | ||
|
|
125 | ref readonly var areaComponent = ref GetComponent<AreaComponent>(entity); | ||
|
|
126 | |||
|
|
127 | foreach (var square in areaComponent.squares) { | ||
|
|
128 | preserve_cells.Add(this.simulation.map.cells[(int)square.X][(int)square.Y]); | ||
|
|
129 | preserve_cell_coordinates.Add(((int)square.X, (int)square.Y)); | ||
|
|
130 | } | ||
|
|
131 | } | ||
|
|
132 | iterPreserves.Stop(); | ||
|
|
133 | Logging.Info(String.Format("Preserve entities: {0:F3}", iterPreserves.Elapsed.TotalMilliseconds.ToString())); | ||
|
|
134 | |||
|
|
135 | |||
|
|
136 | Stopwatch iterCells = new Stopwatch(); | ||
|
|
137 | iterCells.Start(); | ||
|
|
138 | |||
|
|
139 | //This takes about 30ms versus the .0002 ms with no preserve. | ||
|
|
140 | //When the map is filled up with preserve, about 35ms and 9ms. | ||
|
|
141 | //With a handful of cells, it's more like 0.8ms | ||
|
|
142 | /* | ||
|
|
143 | for (int j = 0; j < this.simulation.PreserveCounts.GetLength(0); j++) { | ||
|
|
144 | for (int k = 0; k < this.simulation.PreserveCounts.GetLength(0); k++) { | ||
|
|
145 | count = 0; | ||
|
|
146 | foreach (var cell in this.simulation.map.iterate_neighbor_cells(j, k)) { | ||
|
|
147 | if (preserve_cells.Contains(cell)) { | ||
|
|
148 | count++; | ||
|
|
149 | } | ||
|
|
150 | } | ||
|
|
151 | this.simulation.PreserveCounts[j, k] = count; | ||
|
|
152 | } | ||
|
|
153 | } | ||
|
|
154 | //*/ | ||
|
|
155 | |||
|
|
156 | //* | ||
|
|
157 | foreach ((var x, var y) in preserve_cell_coordinates) { | ||
|
|
158 | foreach ((var newx, var newy) in this.simulation.map.iterate_neighbor_cell_locations(x, y)) { | ||
|
|
159 | |||
|
|
160 | this.simulation.PreserveCounts[newx, newy] += 1; | ||
|
|
161 | } | ||
|
|
162 | |||
|
|
163 | } | ||
|
|
164 | //*/ | ||
|
|
165 | |||
|
|
166 | |||
|
|
167 | iterCells.Stop(); | ||
|
|
168 | Logging.Info(String.Format("Cell loop: {0:F3}", iterCells.Elapsed.TotalMilliseconds.ToString())); | ||
|
|
169 | |||
|
|
170 | #endregion | ||
|
136 | SendMessage<TickMessage>(new TickMessage { SimulationDateTime = simulation.DateTime }); |
|
171 | SendMessage<TickMessage>(new TickMessage { SimulationDateTime = simulation.DateTime }); |
|
137 | //For now: |
|
172 | //For now: |
|
138 | SendMessage<SpawnContractMessage>(new SpawnContractMessage |
|
173 | SendMessage<SpawnContractMessage>(new SpawnContractMessage |
You need to be logged in to leave comments.
Login now