【问题标题】:Why search in .Net Dictionary is slower than in .Net List为什么在 .Net 词典中搜索比在 .Net 列表中慢
【发布时间】:2020-10-15 09:17:01
【问题描述】:

我试图解决这个任务:
我们有一个数组,例如。 [1, 1, 2, 3, 5, 2, 7, 8, 1],查找并输出重复项。对于这个数组,结果是
1、2。

我编写代码来尝试“慢”和“快”解决方案。
带有内循环和通过列表搜索的“慢”解决方案

   public uint[] InnerLoops(uint[] arr)
    {
        var timer = new Stopwatch();
        timer.Start();

        var result = new List<uint>();
        for (int i = 0; i < arr.Length; i++)
        {
            for (int j = i + 1; j < arr.Length; j++)
            {
                if (arr[i] == arr[j] && result.All(a => a != arr[j]))
                    result.Add(arr[j]);
            }
        }

        timer.Stop();

        Console.WriteLine($"Seconds: {timer.Elapsed}");

        return result.ToArray();
    }

我将每个内部循环内的解决方案估计为 O(n^2) 和 O(n)。抱歉,我不擅长估计复杂性。无论如何,我认为,以下解决方案会更好

 public uint[] OneLoopDictionary(uint[] arr)
    {
        var timer = new Stopwatch();
        timer.Start();

        var dictionary = new Dictionary<uint, bool>();
        for (int i = 0; i < arr.Length; i++)
        {
            // Key - number, value - true if duplicates
            if (dictionary.ContainsKey(arr[i]))
            {
                dictionary[arr[i]] = true;
            }
            else
            {
                dictionary[arr[i]] = false;
            }
        }

        var result = new List<uint>();
        foreach (var item in dictionary)
        {
            if (item.Value)
                result.Add(item.Key);
        }

        timer.Stop();

        Console.WriteLine($"Seconds: {timer.Elapsed}");

        return result.ToArray();
    }

复杂度为 O(2n) - 一个循环,通过字典循环。

我很惊讶第一个带有循环的解决方案比第二个解决方案更快。谁能解释一下为什么?

【问题讨论】:

  • 访问字典/哈希表也有开销,这对于 n 的小值尤其明显
  • 另外,秒表不是基准测试工具
  • @TheGeneral 你认为我们可以在 T 恤上使用它吗?
  • @John shirt.SetText("Stopwatch is not a benchmarking tool")

标签: c# time-complexity


【解决方案1】:

谢谢大家!特别是谁给了建议尝试更大的数组。我尝试了 100、1000 和 100000,我很惊讶,字典速度更快。当然,以前,我不仅尝试使用第一篇文章中的数组,还尝试使用大约 50 个数字的数组,但字典速度较慢。

如果有 100 个或更多数字,字典会更快。 100000 个项目的结果是:
列表 - 31 秒,
字典 - 0.008 秒

【讨论】:

    猜你喜欢
    • 2022-08-02
    • 1970-01-01
    • 2023-02-01
    • 2015-10-24
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    相关资源
    最近更新 更多