假设我们有很多点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();
如果您不介意对原始列表进行排序,那么这可能是内存使用率和速度之间的最佳平衡