C# 缓慢搜索

标签 c# performance sorting

我制作了一个简单的数组,其中包含 2,000,000 个整数,用于保存所有 RGB,而第二个数组则用于保存 2,000,000 个整数,用于保存 RGB 被检测到的次数。然后我让它循环遍历图片的所有 6,000,000 字节,如下所示:

        uint[] colors = new uint[rawImageBytes.Length / 3];
        int[] hits    = new int[rawImageBytes.Length / 3];

        int colorAmount     = 0;
        int totalRepeats    = 0;
        int lastTime        = Environment.TickCount;
        int lastCount       = 0;
        uint currentColor   = 0;
        bool found;

        for (int i = 0; i < rawImageBytes.Length - 3; i += 3)
        {
            if (Environment.TickCount - lastTime > 10000)
            {
                setStatus(((i - lastCount)/10) + " checks per second");
                lastTime = Environment.TickCount;
                lastCount = i;
            }


            currentColor = (uint)((rawImageBytes[i] << 0) | (rawImageBytes[i + 1] << 8) | (rawImageBytes[i + 2] << 16));

            //set it to false to see if pattern exists
            found = false;

            //check all patterns
            for (int k = 0; k < colorAmount; k++)
            {
                //if pattern exists
                if (colors[k] == currentColor)
                {
                    //dont add it and increase the hit instead
                    found = true;
                    hits[k]++;
                }
            }

            //if pattern does not exist, set it
            if (found == false)
            {
                colors[colorAmount] = currentColor;
                hits[colorAmount] = 0;
                colorAmount++;
            }
        }

我的日志显示,随着搜索范围的增加,它们的速度显着减慢

5724 checks per second

5847 checks per second

5959 checks per second

6044 checks per second

6318 checks per second

7096 checks per second

8530 checks per second

10680 checks per second

16233 checks per second

11469 checks per second

如何提高搜索效率,以免花费 20 分钟?

最佳答案

我看到的第一个问题是您的点击数组非常大。如果您假设一种颜色可能被多次命中,那么您的命中数组必须比您的颜色数组短。

我看到的第二个问题是,在颜色数组中找到颜色后,您不会停止迭代。您应该将 break; 放在 found = true; 语句之后。

为什么您不喜欢使用 Dictionary< uint,int> 类型作为您的点击集合?您的颜色应该是一个键,点击次数应该是一个值:

    uint[] colors = new uint[rawImageBytes.Length / 3];
    Dictionary<uint,int> hits    = new Dictionary<uint,int>();

    int colorAmount     = 0;
    int totalRepeats    = 0;
    int lastTime        = Environment.TickCount;
    int lastCount       = 0;
    uint currentColor   = 0;


    for (int i = 0; i < rawImageBytes.Length - 3; i += 3)
    {
        if (Environment.TickCount - lastTime > 10000)
        {
            setStatus(((i - lastCount)/10) + " checks per second");
            lastTime = Environment.TickCount;
            lastCount = i;
        }


        currentColor = (uint)((rawImageBytes[i] << 0) | (rawImageBytes[i + 1] << 8) | (rawImageBytes[i + 2] << 16));


        if (hits.ContainsKey(currentColor))
        {
            hits[currentColor]++;
        }
        else
        {
            hits.Add(currentColor,1);
        }

    }

并尝试启用 optimization instruction for compiler

关于C# 缓慢搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9758340/

相关文章:

c# - Dapper 一对多关系

c# - PubSubEvent<TPayload> 类和 CompositePresentationEvent<TPayload> 类之间的 Prism EventAggregator 区别

javascript - 在 Angularjs 和 WebApi 中下载 Excel 文件 xlsx

mysql - 对于一个表中的每组关键字,在第二个表中查找所有匹配的匹配项

javascript - 重用共享 Controller 的功能,为每个页面维护单独的状态

带有交换计数的 Python 冒泡排序列表

c# - 如何从包含一个相等值和一个更大值的数组中选择一行,并用逗号分隔?

performance - 降低了 x64 目标上的 F# 性能?

c++ - 使编译器/优化器能够制作更快的程序的编码实践

java - 如何按 POJO 属性降序排列列表?