はより速く実行し、あなたのコードを少し変更したバージョンは、あなたがC#で、安全でない/ポインタ演算を試すことができます...(これはより速く、安全でない/ポインタコードよりも)
static double FindMaxFastest(double[] x, int startIndex, int endIndex)
{
int i = startIndex;
double max = double.MinValue;
do
{
if (max < x[i])
max = x[i];
} while (i++ < endIndex);
return max;
}
ですが、それは勝ちましたあなたが期待するブーストを得ることはできません。 unsafe
は、コンパイラとランタイムが内部最適化のいくつかを行うことができないため、パフォーマンスを低下させる可能性もあります。
static unsafe double FixMaxFixed(double[] doubles, int startIndex, int endIndex)
{
var i = startIndex;
double max = double.MinValue;
fixed (double* p = doubles)
{
do
{
if (max < *(p + i))
max = *(p + i);
} while (i++ < endIndex);
}
return max;
}
...ここで私が使用したテストハーネスは...セットが降順である場合
static void Main()
{
var rnd = new Random();
var set = Enumerable.Range(0, 10000000).Select(i => rnd.NextDouble() * 100).ToArray();
var s = 50;
var e = 1000000;
var sw = new Stopwatch();
var r = new[] { new List<long>(), new List<long>(), new List<long>() };
for (var i = 0; i < 1000; i++)
{
sw.Restart();
FixMaxFixed(set, s, e);
sw.Stop();
r[0].Add(sw.ElapsedTicks);
sw.Restart();
FindMax(set, s, e);
sw.Stop();
r[1].Add(sw.ElapsedTicks);
sw.Restart();
FindMaxFastest(set, s, e);
sw.Stop();
r[2].Add(sw.ElapsedTicks);
}
//5721.785 6098.866 5432.225
Console.WriteLine(string.Join(" ", r.Select(i => i.Average())));
Console.Read();
}
... Duff's deviceを使用すると、実際の性能(unrolling your loop)を増やすことができます...
(これが私の最初の例の50%の時間で実行されます。あなただけのアイデアを探しているなら...、あなたはそれが昇順であれば、時間の75%)
static double FindMaxDuff(double[] x, int startIndex, int endIndex)
{
double max = x[startIndex];
switch ((endIndex - startIndex) % 10)
{
case 0:
if (max < x[startIndex++]) max = x[startIndex];
goto case 9;
case 9:
if (max < x[startIndex++]) max = x[startIndex];
goto case 8;
case 8:
if (max < x[startIndex++]) max = x[startIndex];
goto case 7;
case 7:
if (max < x[startIndex++]) max = x[startIndex];
goto case 6;
case 6:
if (max < x[startIndex++]) max = x[startIndex];
goto case 5;
case 5:
if (max < x[startIndex++]) max = x[startIndex];
goto case 4;
case 4:
if (max < x[startIndex++]) max = x[startIndex];
goto case 3;
case 3:
if (max < x[startIndex++]) max = x[startIndex];
goto case 2;
case 2:
if (max < x[startIndex++]) max = x[startIndex];
goto case 1;
case 1:
if (max < x[startIndex++]) max = x[startIndex];
break;
}
do
{
if (max < x[startIndex + 1]) max = x[startIndex + 1];
if (max < x[startIndex + 2]) max = x[startIndex + 2];
if (max < x[startIndex + 3]) max = x[startIndex + 3];
if (max < x[startIndex + 4]) max = x[startIndex + 4];
if (max < x[startIndex + 5]) max = x[startIndex + 5];
if (max < x[startIndex + 6]) max = x[startIndex + 6];
if (max < x[startIndex + 7]) max = x[startIndex + 7];
if (max < x[startIndex + 8]) max = x[startIndex + 8];
if (max < x[startIndex + 9]) max = x[startIndex + 9];
if (max < x[startIndex + 10]) max = x[startIndex + 10];
} while ((startIndex += 10) < endIndex);
return max;
}
、n個のグループに配列を分割し、n個のスレッドで並行してこのコードを実行し、取ることができますそれらの最大値の最大値。 – Forklift
代わりに配列をソートするか、バイナリ検索ツリーを使用できますか? – EJoshuaS
アレイをソートすると、その中の最後の項目を取ることができます –