Speed up SpatiallyPartitioned.InBox for searches in a single partition bin.
If a search in a spatial partition is taking place entirely within a single bin, the cost of tracking possible duplicate items with a set can be avoided for a small speedup.
This commit is contained in:
@@ -86,7 +86,11 @@ namespace OpenRA.Primitives
|
|||||||
var top = (box.Top / binSize).Clamp(0, rows - 1);
|
var top = (box.Top / binSize).Clamp(0, rows - 1);
|
||||||
var bottom = (box.Bottom / binSize).Clamp(0, rows - 1);
|
var bottom = (box.Bottom / binSize).Clamp(0, rows - 1);
|
||||||
|
|
||||||
var items = new HashSet<T>();
|
// We want to return any items intersecting the box.
|
||||||
|
// If the box covers multiple bins, we must handle items that are contained in multiple bins and avoid
|
||||||
|
// returning them more than once. We shall use a set to track these.
|
||||||
|
// PERF: If we are only looking inside one bin, we can avoid the cost of performing this tracking.
|
||||||
|
var items = top == bottom && left == right ? null : new HashSet<T>();
|
||||||
for (var row = top; row <= bottom; row++)
|
for (var row = top; row <= bottom; row++)
|
||||||
for (var col = left; col <= right; col++)
|
for (var col = left; col <= right; col++)
|
||||||
{
|
{
|
||||||
@@ -96,10 +100,12 @@ namespace OpenRA.Primitives
|
|||||||
var item = kvp.Key;
|
var item = kvp.Key;
|
||||||
var bounds = kvp.Value;
|
var bounds = kvp.Value;
|
||||||
|
|
||||||
// Return items that intersect the box. We also want to avoid returning the same item many times.
|
// If the item is in the bin, we must check it intersects the box before returning it.
|
||||||
// If the item is contained wholly within this bin, we're good as we know it won't show up in any others.
|
// We shall track it in the set of items seen so far to avoid returning it again if it appears
|
||||||
// Otherwise it may appear in another bin. We use a set of seen items to avoid yielding it again.
|
// in another bin.
|
||||||
if (bounds.IntersectsWith(box) && (binBounds.Contains(bounds) || items.Add(item)))
|
// PERF: If the item is wholly contained within the bin, we can avoid the cost of tracking it.
|
||||||
|
if (bounds.IntersectsWith(box) &&
|
||||||
|
(items == null || binBounds.Contains(bounds) || items.Add(item)))
|
||||||
yield return item;
|
yield return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user