以下代码:
List<Interval> intervals = new List<Interval>();
List<int> points = new List<int>();
//Initialization of the two lists
// [...]
foreach (var point in points)
{
intervals.RemoveAll (x => x.Intersects (point));
}
当列表的大小约为10000时,它至少比此快100倍:
List<Interval> intervals = new List<Interval>();
List<int> points = new List<int>();
//Initialization of the two lists
// [...]
foreach (var point in points)
{
for (int i = 0; i < intervals.Count;)
{
if (intervals[i].Intersects(point))
{
intervals.Remove(intervals[i]);
}
else
{
i++;
}
}
}
怎么可能? "RemoveAll"在幕后执行了什么操作?根据MSDN的说法,"RemoveAll"执行线性搜索,因此其时间复杂度为O(n)。因此我预计两者具有相似的性能表现。
将"Remove"替换为"RemoveAt"后,迭代速度会更快,与"RemoveAll"相当。但是,两者"Remove"和"RemoveAt"的时间复杂度都为O(n),那么它们之间的性能差异为什么这么大?难道这只是因为"Remove(item)"将列表元素与"item"进行比较,而"RemoveAt"不执行任何比较吗?
intervals.RemoveAt(i);
而不是intervals.Remove(intervals[i]);
,我认为你可以加快第二个代码示例的速度。 - AShRemoveAll
和Remove
都是O(n)
的,因此很容易相信那个额外有一个for
循环的函数会慢n
倍。 - vgruRemoveAll
和LINQ的组合:intervals.RemoveAll(i => points.Any(p => i.Intersects(p)));
- Tim Schmelter