技术点滴-C# 12 和 .NET 8 中字典与列表的性能

作者:微信公众号:【架构师老卢】
7-11 18:23
34

概述:两种数据结构在性能方面如何比较?许多开发人员可以互换使用不同的数据结构,而没有意识到某些数据结构比其他数据结构更好,具体取决于手头的任务。当今硬件和系统的速度如此之快,以至于在许多情况下,不同数据结构之间的性能差异在实际使用中并不明显。我认为这导致了它们的潜在滥用。一个非常常见的示例是使用 List 和 Dictionary 数据结构。在做了多年的代码审查之后,我一直注意到在许多情况下使用 List 而不是 Dictionary,而 Dictionary 本来是更好的选择。本文将展示 List 和 Dictionary 之间的性能差异的示例。我是一名 C# 开发人员,所以我将使用 .NET 8

两种数据结构在性能方面如何比较?

许多开发人员可以互换使用不同的数据结构,而没有意识到某些数据结构比其他数据结构更好,具体取决于手头的任务。

当今硬件和系统的速度如此之快,以至于在许多情况下,不同数据结构之间的性能差异在实际使用中并不明显。我认为这导致了它们的潜在滥用。

一个非常常见的示例是使用 List 和 Dictionary 数据结构。在做了多年的代码审查之后,我一直注意到在许多情况下使用 List 而不是 Dictionary,而 Dictionary 本来是更好的选择。

本文将展示 List 和 Dictionary 之间的性能差异的示例。

我是一名 C# 开发人员,所以我将使用 .NET 8,而 .NET 8 又使用 C# 12 来证明我的观点。

我将创建一个简单的控制台应用程序,并使用 stopwatch 类来跟踪执行从集合中查找对象的基本数据操作所需的时间。

检索对象

为简单起见,我将使用以下对象进行比较。

var list = new List<Tuple<string, string>>(); // Tuple list   
var dictionary = new Dictionary<string, string>(); // Dictionary with string, string key value items

Tuple 类类似于 Dictionary 对象中使用的 KeyValue 对,这就是为什么我认为它是 List 的一个很好的替代词

如果这是一个真实的应用程序,那么这两种类型的集合都可以用来实现类似的结果(在一定程度上),但让我们看看使用一个集合对性能的影响。

首先,我使用相同的数据填充两个集合,在我的情况下,这些数据将是 1 到 100.000 之间的数字。

// add to collection
var list = new List<Tuple<string, string>>();
var dictionary = new Dictionary<string, string>();
var keyConstant = "key_";

for (int i = 1; i < 100000; i++)
{
    list.Add(new Tuple<string, string>(keyConstant + i.ToString(), i.ToString()));
    dictionary.Add(keyConstant + i.ToString(), i.ToString());
}

然后我们开始讨论有趣的事情。

var lookupValue = "key_56398";

// Lookup dictionary
var sw1 = new Stopwatch();

sw1.Start();
var test1 = list.FirstOrDefault(x => x.Item1 == lookupValue);
sw1.Stop();

var listTimer = sw1.Elapsed.TotalMilliseconds;

// Lookup dictionary
var sw2 = new Stopwatch();

sw2.Start();
var test2 = dictionary[lookupValue];
sw2.Stop();
var dicTimer = sw2.Elapsed.TotalMilliseconds;

Console.WriteLine("RETRIEVE FROM LIST: " + listTimer);
Console.WriteLine("RETRIEVE FROM DICTIONARY: " +  dicTimer);  

在上面的代码中,我使用两个秒表对象来跟踪执行查找操作以通过其键在相应集合中查找项目所需的时间。

我选择使用“**.FirstOrDefault()“**方法,因为我认为这是获取与给定条件匹配的第一个元素的最实用方法。

最后,秒表输出以毫秒为单位打印,这是结果。

如您所见,从字典中检索项目比从常规列表中检索相同的操作性能和效率要高得多**(1.4 毫秒对 0.01 毫秒)。**
这是因为字典作为一种数据结构,就是为此目的而设计的。当通过其键查找值时,它不需要遍历集合中的所有项目(就像列表那样)。相反,它使用哈希表来检索映射到该键的对象,这要快得多。

当您需要对数据执行大量查找操作时,请使用 Dictionary 数据结构。它是为此目的而构建的,而且速度非常快。在处理大型或复杂的数据集以及执行时间非常重要时,这一点尤其明显。请记住,毫秒可能会加起来,尤其是在需要扩大相关应用程序规模的情况下。

当您经常在集合中添加/删除项时,或者当您需要对数据执行排序和排序操作时,请使用 List 结构。

阅读排行