假设我们有很多点List<Point> pointList(已经存储在内存中),其中每个Point包含X,Y和Z坐标。

现在,我想选择存储在pointList中的所有点的Z%值最大的N%点。现在我正在这样做:

N = 0.05; // selecting only 5% of points
double cutoffValue = pointList
    .OrderBy(p=> p.Z) // First bottleneck - creates sorted copy of all data
    .ElementAt((int) pointList.Count * (1 - N)).Z;

List<Point> selectedPoints = pointList.Where(p => p.Z >= cutoffValue).ToList();

但是我这里有两个内存使用瓶颈:首先是在OrderBy(更重要)期间,其次是在选择点时(这不太重要,因为我们通常只选择少量点)。

有什么方法可以用内存更少的东西代替OrderBy(或者找到该临界点的其他方法)?

这个问题非常重要,因为LINQ复制了整个数据集,而对于我正在处理的大文件,有时会达到数百MB。

最佳答案

您可以使用List<T>.Sort(使用Quicksort算法)对列表进行排序。但是,当然,您的原始列表将被排序,这可能不是您想要的...

pointList.Sort((a, b) => b.Z.CompareTo(a.Z));
var selectedPoints = pointList.Take((int)(pointList.Count * N)).ToList();

如果您不介意对原始列表进行排序,那么这可能是内存使用率和速度之间的最佳平衡

10-08 19:14