在.NET中比较两种RGB颜色的最快方法是什么?

时间:2017-05-31 14:31:23

标签: c# .net optimization graphics

如果我只需要比较RGB组件,那么还有什么比这更快的吗?

bool ColorChanged(Color a, Color b)
{
    return a.ToArgb() != b.ToArgb();
}

在我们的代码中,这个方法被调用了数百万次,我想知道它是否可以被优化。显然,比较单个RGB值并不快。

编辑:以下是基于SneakyTactician样本的测试,结果有点令人惊讶:直接颜色比较获胜!

static void Main(string[] args)
{
   int len = 10000000;

   Color[] colors1 = new Color[len];
   Color[] colors2 = new Color[len];

   Random rand = new Random();

   for (int i = 0; i < len; i++)
   {
      colors1[i] = Color.FromArgb((int)(rand.NextDouble() * 255), (int)(rand.NextDouble() * 255), (int)(rand.NextDouble() * 255));
      colors2[i] = Color.FromArgb((int)(rand.NextDouble() * 255), (int)(rand.NextDouble() * 255), (int)(rand.NextDouble() * 255));
   }

   Stopwatch sw = new Stopwatch();
   sw.Start();

   for (int i = 0; i < len; i++)
   {
      ColorChanged1(colors1[i], colors2[i]);
   }

   sw.Stop();

   Console.WriteLine("ColorChanged1: " + sw.ElapsedMilliseconds);

   sw.Reset();
   sw.Start();

   for (int i = 0; i < len; i++)
   {
      ColorChanged2(colors1[i], colors2[i]);
   }

   sw.Stop();

   Console.WriteLine("ColorChanged2: " + sw.ElapsedMilliseconds);

   sw.Reset();
   sw.Start();

   for (int i = 0; i < len; i++)
   {
      ColorChanged3(colors1[i], colors2[i]);
   }

   sw.Stop();

   Console.WriteLine("ColorChanged3: " + sw.ElapsedMilliseconds);
}

static bool ColorChanged1(Color a, Color b)
{
   return a.ToArgb() != b.ToArgb();
}

static bool ColorChanged2(Color a, Color b)
{
   return a != b;
}

static bool ColorChanged3(Color a, Color b)
{
   return a.ToKnownColor() != b.ToKnownColor();
}

结果:

ColorChanged1: 206 ms
ColorChanged2: 172 ms
ColorChanged3: 159 ms

2 个答案:

答案 0 :(得分:0)

我对几种不同的颜色比较方法进行了一些基准测试。它们可能并非完全符合您的要求,但也许它们将来会帮助其他人。

测试代码:

    static void Main(string[] args)
    {
        int I = 0;
        int i = 0;

        List<Color> Colors1 = new List<Color>();
        List<Color> Colors2 = new List<Color>();

        while (i != 1000)
        {
            Colors1.Add(RandomColor());
            Colors2.Add(RandomColor());
            i++;
        }

        Stopwatch a = new Stopwatch();

        a.Start();

        while (I != 1000)
        {
            ColorChanged1(Colors1.ElementAt(I), Colors2.ElementAt(I));
            I++;
        }

        a.Stop();

        Console.WriteLine("ColorChanged1: " + a.Elapsed.ToString());

        a.Reset();
        a.Start();

        I = 0;

        while (I != 1000)
        {
            ColorChanged2(Colors1.ElementAt(I), Colors2.ElementAt(I));
            I++;
        }

        a.Stop();

        Console.WriteLine("ColorChanged2: " + a.Elapsed.ToString());

        a.Reset();
        a.Start();

        I = 0;

        while (I != 1000)
        {
            ColorChanged3(Colors1.ElementAt(I), Colors2.ElementAt(I));
            I++;
        }

        a.Stop();

        Console.WriteLine("ColorChanged3: " + a.Elapsed.ToString());
        Console.ReadLine();
    }

    static Color RandomColor()
    {
        Array values = Enum.GetValues(typeof(KnownColor));
        Random random = new Random();
        KnownColor rcolor = (KnownColor)values.GetValue(random.Next(values.Length));

        return Color.FromKnownColor(rcolor);
    }

    static bool ColorChanged1(Color a, Color b)
    {
        return a.ToArgb() != b.ToArgb();
    }

    static bool ColorChanged2(Color a, Color b)
    {
        return a != b;
    }

    static bool ColorChanged3(Color a, Color b)
    {
        return a.ToKnownColor() != b.ToKnownColor();
    }

结果:

ColorChanged1:00:00:00.0142920

ColorChanged2:00:00:00.0001769

ColorChanged3:00:00:00.0001609

答案 1 :(得分:0)

您可以将颜色存储为文字吗?

比较文本比每次比较Color对象和调用ToArgb方法要快。

所以这样做:

bool ColorChanged2(string a, string b)
{
    return a != b;
}

请参阅以下代码...比较字符串的速度通常是其两倍。

    string runTest()
    {
        int howMany = 1000000;

        Color c1 = Color.Red;
        Color c2 = Color.Green;
        string c3 = "FF0000";
        string c4 = "00FF00";

        string result = "";
        Stopwatch sw = new Stopwatch();


        // Compare using Color object
        sw.Start();
        for (int i = 0; i < howMany; i++)
        {
            bool response = ColorChanged1(c1, c2);
        }
        sw.Stop();

        result += "Compare Color objects" + Environment.NewLine;
        result += "Elapsed: " + sw.Elapsed.ToString() + Environment.NewLine;
        result += "" + Environment.NewLine;


        // Compare strings
        sw.Reset();
        sw.Start();
        for (int i = 0; i < howMany; i++)
        {
            bool response = ColorChanged2(c3, c4);
        }
        sw.Stop();

        result += "Compare strings" + Environment.NewLine;
        result += "Elapsed: " + sw.Elapsed.ToString() + Environment.NewLine;
        result += "" + Environment.NewLine;


        return result;
    }

    bool ColorChanged1(Color a, Color b)
    {
        return a.ToArgb() != b.ToArgb();
    }

    bool ColorChanged2(string a, string b)
    {
        return a != b;
    }

<强>结果

比较Color对象 经过时间:00:00:00.0611088

比较字符串 经过时间:00:00:00.0285529

相关问题