double の配列から n 最小 (0 ではない) を見つける必要があります (配列samplesと呼びましょう)。これをループで何度も行う必要があるため、実行速度が重要です。最初に配列をソートしてから、最初の 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 値を最初に読み取り、それらを並べ替え、次にサンプル内の他のすべての値をループして、並べ替えられたlowSamples配列の最後の値よりも値が小さいかどうかを確認するという、別の、しかしクリーンではない解決策を試しました。値が小さい場合は、配列内の値に置き換えて、配列を再度並べ替えます。これは約 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();
}
}
}
これは比較的高速に機能しますが、より高速で優れたソリューションを考え出すように誰かに挑戦したかったのです。