给定两种用整数表示的ARGB颜色,8位/通道(alpha、红色、绿色、蓝色),我需要计算一个表示它们之间某种距离(也是整数)的值。
因此,距离的公式是:Delta=|R1-R2|+|G1-G2|+|B1-B2|,其中Rx、Gx和Bx是颜色1和2的通道的值。Alpha通道始终被忽略。
我需要加速这个计算,因为它在一台速度很慢的机器上做了很多次。在给定两个整数的情况下,在单个线程上计算这个值的“极客”方法是什么?
到目前为止,我最好的是,但我想这还可以进一步改进:
//Used for color conversion from/to int
private const int ChannelMask = 0xFF;
private const int GreenShift = 8;
private const int RedShift = 16;
public int ComputeColorDelta(int color1, int color2)
{
int rDelta = Math.Abs(((color1 >> RedShift) & ChannelMask) - ((color2 >> RedShift) & ChannelMask));
int gDelta = Math.Abs(((color1 >> GreenShift) & ChannelMask) - ((color2 >> GreenShift) & ChannelMask));
int bDelta = Math.Abs((color1 & ChannelMask) - (color2 & ChannelMask));
return rDelta + gDelta + bDelta;
}发布于 2011-09-06 03:43:24
长长的答案:
多少是“很多”
我想我有一台速度很快的机器,但我写了这个小脚本:
public static void Main() {
var s = Stopwatch.StartNew();
Random r = new Random();
for (int i = 0; i < 100000000; i++) {
int compute = ComputeColorDelta(r.Next(255), r.Next(255));
}
Console.WriteLine(s.ElapsedMilliseconds);
Console.ReadLine();
}输出为: 6878
因此,对于一亿次来说,7秒似乎是很好的。
不过,我们绝对可以加快速度。我更改了您的函数,如下所示:
public static int ComputeColorDelta(int color1, int color2) {
return 1;
}更改后,输出为: 5546。因此,通过返回一个常量,我们成功地在1亿次迭代中获得了1秒的性能增益。;)
简而言之:这个函数不是你的瓶颈。:)
发布于 2011-09-06 04:14:14
我正在尝试让运行时为我进行计算。
首先,我定义了带有显式字段偏移量的结构
[StructLayout(LayoutKind.Explicit)]
public struct Color
{
[FieldOffset(0)] public int Raw;
[FieldOffset(0)] public byte Blue;
[FieldOffset(8)] public byte Green;
[FieldOffset(16)] public byte Red;
[FieldOffset(24)] public byte Alpha;
}计算函数为:
public int ComputeColorDeltaOptimized(Color color1, Color color2)
{
int rDelta = Math.Abs(color1.Red - color2.Red);
int gDelta = Math.Abs(color1.Green - color2.Green);
int bDelta = Math.Abs(color1.Blue - color2.Blue);
return rDelta + gDelta + bDelta;
}和用法
public void FactMethodName2()
{
var s = Stopwatch.StartNew();
var color1 = new Color(); // This is a structs, so I can define they out of loop and gain some performance
var color2 = new Color();
for (int i = 0; i < 100000000; i++)
{
color1.Raw = i;
color2.Raw = 100000000 - i;
int compute = ComputeColorDeltaOptimized(color1, color2);
}
Console.WriteLine(s.ElapsedMilliseconds); //5393 vs 7472 of original
Console.ReadLine();
}发布于 2011-09-06 03:24:16
一种想法是使用你已经有的相同的代码,但顺序不同:应用掩码,取差值,然后移位。
另一个可能有帮助的修改是内联这个函数:也就是说,不是为每一对颜色调用它,而是直接在执行此代码的循环中计算差异。我假设它在一个紧凑的循环中,因为否则它的成本将可以忽略不计。
最后,由于您可能会获得图像像素数据,因此使用unsafe方法可以节省大量资源:像这样制作位图,然后获取字节*并从中读取图像数据。
https://stackoverflow.com/questions/7311946
复制相似问题