首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何加速此计算

如何加速此计算
EN

Stack Overflow用户
提问于 2011-09-06 03:15:17
回答 4查看 545关注 0票数 3

给定两种用整数表示的ARGB颜色,8位/通道(alpha、红色、绿色、蓝色),我需要计算一个表示它们之间某种距离(也是整数)的值。

因此,距离的公式是:Delta=|R1-R2|+|G1-G2|+|B1-B2|,其中Rx、Gx和Bx是颜色1和2的通道的值。Alpha通道始终被忽略。

我需要加速这个计算,因为它在一台速度很慢的机器上做了很多次。在给定两个整数的情况下,在单个线程上计算这个值的“极客”方法是什么?

到目前为止,我最好的是,但我想这还可以进一步改进:

代码语言:javascript
复制
    //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;
    }
EN

回答 4

Stack Overflow用户

发布于 2011-09-06 03:43:24

长长的答案:

多少是“很多”

我想我有一台速度很快的机器,但我写了这个小脚本:

代码语言:javascript
复制
 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秒似乎是很好的。

不过,我们绝对可以加快速度。我更改了您的函数,如下所示:

代码语言:javascript
复制
public static int ComputeColorDelta(int color1, int color2) {
  return 1;
}

更改后,输出为: 5546。因此,通过返回一个常量,我们成功地在1亿次迭代中获得了1秒的性能增益。;)

简而言之:这个函数不是你的瓶颈。:)

票数 3
EN

Stack Overflow用户

发布于 2011-09-06 04:14:14

我正在尝试让运行时为我进行计算。

首先,我定义了带有显式字段偏移量的结构

代码语言:javascript
复制
[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;
}

计算函数为:

代码语言:javascript
复制
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;
}

和用法

代码语言:javascript
复制
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();
}
票数 2
EN

Stack Overflow用户

发布于 2011-09-06 03:24:16

一种想法是使用你已经有的相同的代码,但顺序不同:应用掩码,取差值,然后移位。

另一个可能有帮助的修改是内联这个函数:也就是说,不是为每一对颜色调用它,而是直接在执行此代码的循环中计算差异。我假设它在一个紧凑的循环中,因为否则它的成本将可以忽略不计。

最后,由于您可能会获得图像像素数据,因此使用unsafe方法可以节省大量资源:像这样制作位图,然后获取字节*并从中读取图像数据。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7311946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档