其中一个明显更快吗?
var scan0 = (uint*)bitmapData.Scan0;
int length = pixels.Length;
for (int i = 0; i < length; i++)
{
uint j = scan0[i];
float a = (j >> 24) / 255f;
pixels[i] = new Vector(
(j >> 16 & 0xff) * a / 255,
(j >> 8 & 0xff) * a / 255,
(j & 0xff) * a / 255);
}
与
var scan0 = (byte*)bitmapData.Scan0;
int length = pixels.Length * 4;
for (int i = 0; i < length; i += 4)
{
float a = scan0[i + 3] / 255f;
pixels[i / 4] = new Vector(
scan0[i + 2] * a / 255,
scan0[i + 1] * a / 255,
scan0[i] * a / 255);
}
答案 0 :(得分:4)
在32位应用程序中,第二个应用程序比第一个应用程序快2.5倍。在64位应用程序中,第二个应用程序比第一个应用程序快25%。
请注意,您的第二个代码中存在错误。当您在每次迭代中添加四个时,您将把对象放在pixels
数组中的每四个项目中,并在数组用完时导致IndexOutOfRangeException
异常。
比第二个更快(约5%)移动每个像素的指针:
byte* scan0 = (byte*)bitmapData.Scan0;
for (int i = 0; i < pixels.Length; i++) {
float a = scan0[3] / 255f;
pixels[i] = new Vector(
scan0[2] * a / 255,
scan0[1] * a / 255,
scan0[0] * a / 255
);
scan0 += 4;
}
另请注意,如果您正在从Bitmap
图像中读取数据,则不会将其存储为连续的像素数据数组。扫描线之间可能存在填充,因此代码只能从单条扫描线读取像素,无法安全地从整个图像中读取数据。
另外,我刚刚意识到你将数组的长度放在一个变量中并在循环中使用它。这将使代码变慢而不是更快,因为编译器无法优化数组访问的范围检查。
答案 1 :(得分:0)
我认为“你的第一个解决方案”的位移更快。但是您可以使用Stopwatch
进行测试。在调用方法之前启动stopwatch
,多次运行该方法,然后停止监视并检查其ElapcedMilliseconds
。像:
System.Diagnostics.Stopwatch watch = Stopwatch.StartNew();
//run your method that want to test its executable time multi time
for (int testIndex = 0; testIndex < 100; testIndex++)
{
TestWithShift();
}
watch.Stop();
Console.WriteLine("Test with shift time: {0}", watch.ElapcedMilliseconds);
并重复其他方法的测试。希望有所帮助。