修改List <t> fast </t>中的项目

时间:2011-04-30 19:27:41

标签: c#

我尝试使用Parallel.ForEach和ConcurrentBag使这段代码执行得更快但是它仍然运行得很长(特别是考虑到在我的场景中我可能也是1.000.000 ++):

List<Point> points = new List<Point>();
for(int i = 0; i<100000;i++) {
    Point point = new Point {X = i-50000, Y = i+50000, CanDelete = false};
    points.Add(point);
}

foreach (Point point in points) {
    foreach (Point innerPoint in points) {
        if (innerPoint.CanDelete == false && (point.X - innerPoint.X) < 2) {
            innerPoint.Y = point.Y;
            point.CanDelete = true;
        }
    }
}

2 个答案:

答案 0 :(得分:5)

由于数据访问模式,该代码将并行执行WORSE。

加快速度的最佳方法是识别您不需要考虑所有O(N ^ 2)个点,而只需要考虑具有X坐标附近的点。

首先,按X坐标O(N log N)对列表进行排序,然后从每个点开始向前和向后处理列表,直到离开邻域为止。您需要使用索引而不是foreach

如果是您的样本数据,则该列表已经排序。

由于您的距离测试是对称的,并且从考虑中删除了匹配点,因此您可以跳过查看之前的点。

for (int j = 0; j < points.Length; ++j) {
  int x1 = points[j].X;
  //for (int k = j; k >= 0 && points[k].X > x1 - 2; --k ) { /* merge points */ }
  for (int k = j + 1; k < points.Length && points[k].X < x1 + 2; ++k ) { /* merge points */ }
}

不仅复杂性更好,缓存行为也更优越。它可以在多个线程之间拆分,缓存争用更少。

答案 1 :(得分:2)

好吧,我不确切地知道你想要什么,但试试吧。

首先,在创建List时,您可能希望设置所需的初始大小,因为您知道它将保留多少项。所以它不需要一直在增长。

List<Point> points = new List<Point>(100000);

接下来,您可以按X属性对列表进行排序。因此,您只需将每个点与其附近的点进行比较:当您找到第一个,向前或向后的距离太远时,您可以停止比较。

相关问题