самый быстрый способ получить n наименьших значений из массива

Мне нужно найти 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();
        }
    }
}

Хотя это работает относительно быстро, я хотел призвать любого предложить еще более быстрое и лучшее решение.

9
задан Roger Saele 28 June 2012 в 14:57
поделиться