我需要找到一个double类型数组(我们称其为samples)中前n个最小值(排除0)。我需要在循环中多次执行此操作,因此执行速度非常关键。我尝试首先对数组进行排序,然后取前10个值(不包括0),但是,虽然Array.Sort被认为很快,但它成为了瓶颈:
const int numLowestSamples = 10;
double[] samples;
double[] lowestSamples = new double[numLowestSamples];
for (int count = 0; count < iterations; count++) // iterations typically around 2600000
{
samples = whatever;
Array.Sort(samples);
lowestSamples = samples.SkipWhile(x => x == 0).Take(numLowestSamples).ToArray();
}
因此,我尝试了一种不太简洁的解决方案,首先读取前n个值,将它们排序,然后循环遍历samples中的所有其他值,检查该值是否小于已排序的lowestSamples数组中的最后一个值。如果该值较低,则用数组中的值替换它,并再次对数组进行排序。结果发现这种方法大约快了5倍:
const int numLowestSamples = 10;
double[] samples;
List<double> lowestSamples = new List<double>();
for (int count = 0; count < iterations; count++) // iterations typically around 2600000
{
samples = whatever;
lowestSamples.Clear();
// Read first n values
int i = 0;
do
{
if (samples[i] > 0)
lowestSamples.Add(samples[i]);
i++;
} while (lowestSamples.Count < numLowestSamples)
// Sort the array
lowestSamples.Sort();
for (int j = numLowestSamples; j < samples.Count; j++) // samples.Count is typically 3600
{
// if value is larger than 0, but lower than last/highest value in lowestSamples
// write value to array (replacing the last/highest value), then sort array so
// last value in array still is the highest
if (samples[j] > 0 && samples[j] < lowestSamples[numLowestSamples - 1])
{
lowestSamples[numLowestSamples - 1] = samples[j];
lowestSamples.Sort();
}
}
}
虽然这个方法相对比较快,但我想挑战任何人提出更快更好的解决方案。