我提前为这个问题的长度道歉......这有点牵扯。我正在编写一个非常简单的“加权和”运算;取 n 个图像,将每个图像乘以特定的乘数并将它们相加成输出图像(通过迭代每个像素)。当图像数量不变时,我可以将逻辑硬编码到一次迭代中,但是,我希望使该方法足够灵活以处理可变数量的图像。我无法想出一个同样“高效”的方法来实现这一点,例如,当输入数量未知时,没有额外的内部循环。这是我的情况:
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 - 一旦构建,它将以一维数组作为像素源(因为高度/宽度被传递给构造函数)
- 每个输入图像都有一个特定的乘数,例如将输入 1 的所有像素乘以 2,将输入 2 的所有像素乘以 3,等等。
- 输入永远不会超过 20 个。