この質問が長くなってしまうことをお詫びします...少し複雑です。私は非常に単純な「加重合計」操作を書いています。n 個の画像を取得し、各画像に特定の乗数を掛けて、出力画像に合計します (各ピクセルを反復することにより)。画像の数が一定の場合、ロジックを 1 回の反復にハードコーディングできますが、可変数の画像を処理できるようにメソッドを柔軟にしたいと考えています。入力の数が不明な場合に追加の内部ループを使用しないなど、これを達成するための同等に「パフォーマンスの高い」方法を思いつくことはできません。これが私の状況です:
var rnd = new Random();
//Pixels in input and output images
const int x = 1000000;
//An output composite image
var pixelmap = new int[x];
var tStart = DateTime.Now;
//Known number of inputs
int knownNumberOfInputs = 3;
//Weights to apply to each pixel of the input images
//multipliers[0] applies to all pixels of inputA,
//multipliers[1] applies to all pixels of inputB etc.
var multipliers = new byte[3];
rnd.NextBytes(multipliers);
/* situation 1
* - I know how many input images
* - Arrays are independent */
//3 (knownNumberOfInputs) input images (we'll use random numbers for filler)
var inputA = new byte[x];
rnd.NextBytes(inputA);
var inputB = new byte[x];
rnd.NextBytes(inputB);
var inputC = new byte[x];
rnd.NextBytes(inputC);
//I can iterate through each pixel of each input image, multiply and sum for pixelmap value.
//Without a nested loop
for (var i = 0; i < x; i++)
{
pixelmap[i] = (
(inputA[i]*multipliers[0]) +
(inputB[i]*multipliers[1]) +
(inputC[i]*multipliers[2])
);
}
Console.WriteLine("Operation took " + DateTime.Now.Subtract(tStart).TotalMilliseconds + " ms");
// Operation took 39 ms
tStart = DateTime.Now;
/* situation 2
* unknown number of inputs
* inputs are contained within jagged array */
/* Caveat - multipliers.Length == inputs.Length */
//var unknownNumberOfInputs = rnd.Next(1, 10);
var unknownNumberOfInputs = 3; //Just happens to be the same number (for performance comparisons)
multipliers = new byte[unknownNumberOfInputs];
rnd.NextBytes(multipliers);
//Jagged array to contain input images
var inputs = new byte[unknownNumberOfInputs][];
//Load unknownNumberOfInputs of input images into jagged array
for (var i = 0; i < unknownNumberOfInputs; i++)
{
inputs[i] = new byte[x];
rnd.NextBytes(inputs[i]);
}
// I cannot iterate through each pixel of each input image
// Inner nested loop
for (var i = 0; i < x; i++)
{
for (var t=0;t<multipliers.Length;t++)
{
pixelmap[i] += (inputs[t][i] * multipliers[t]);
}
}
Console.WriteLine("Operation took " + DateTime.Now.Subtract(tStart).TotalMilliseconds + " ms");
//Operation took 54 ms
//How can I get rid of the inner nested loop and gain the performance of LoopA?
//Or is that the cost of not knowing?
ビッグアップ
もう少し情報
- ピクセルマップは、Silverlight の WriteableBitmap に入ります。これは、構築されると、1D 配列をピクセル ソースとして受け取ります (高さ/幅がコンストラクターに渡されるため)。
- 各入力画像には特定の乗数があります。たとえば、入力 1 のすべてのピクセルに 2 を掛けたり、入力 2 のすべてのピクセルに 3 を掛けたりします。
- 入力が 20 を超えることはありません。