Мне нужно найти 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 значений, отсортировав их, затем перебрав все остальные значения в выборках , проверяя, меньше ли значение, чем последнее значение в отсортированном массив наименьших образцов . Если значение ниже, замените его значением в массиве и снова отсортируйте массив. Это оказалось примерно в 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();
}
}
}
Хотя это работает относительно быстро, я хотел призвать любого предложить еще более быстрое и лучшее решение.