.NET 9 —LINQ — 新的索引方法

科技   2024-12-19 05:59   上海  


在.NET 9中,引入了新的LINQ方法Index(即Index<TSource>(IEnumerable<TSource>))。借助这个方法,你可以轻松提取可枚举对象的隐式索引。

在之前的一篇文章中,我展示了.NET 9中新增的三个LINQ方法:CountByAggregateByIndex。在本文中,我想重点介绍Index方法,并展示在早期.NET版本中实现类似结果的替代方法,同时进行性能基准测试来比较它们的性能。

Index方法

Index方法返回一个元组(IEnumerable<(int Index, TSource Item)>),其中第一个值是索引,第二个值是集合中的元素。

为了演示这个方法的工作原理,我创建了一个城市列表,它将用于以下示例中:

public class City
{
public string Name { get; set; }
public string Country { get; set; }

public City(string name, string Country)
{
Name = name;
Country = Country;
}
}

var cities = new List<City>()
{
new City("Paris", "France"),
new City("Berlin", "Germany"),
new City("Madrid", "Spain"),
new City("Rome", "Italy"),
new City("Amsterdam", "Netherlands")
};

使用Index方法,我们可以通过foreach循环轻松获取列表的索引和元素,如下所示:

foreach ((int index, City city) in cities.Index())
{
Console.WriteLine($"Index: {index}, City: {city.Name}");
}

请注意,Index方法返回一个元组,其中第一个值是索引,第二个值是元素本身。输出结果如下:

Index: 0, City: Paris
Index: 1, City: Berlin
Index: 2, City: Madrid
Index: 3, City: Rome
Index: 4, City: Amsterdam

另一种实现相同结果的方法

在早期的.NET版本中,我们也可以通过使用Count以及传统的for循环来实现相同的结果,如下所示:

var citiesCount = cities.Count();

for (int i = 0; i < citiesCount; i++)
{
Console.WriteLine($"Index: {i}, City: {cities[i].Name}");
}

另一种方法是使用LINQ的Select方法来获取集合中有索引的元素,然后通过foreach循环对其进行迭代,如下所示:

var indexedElements = cities.Select((item, index) => 
new { Index = index, Item = item });

foreach (var item in indexedElements)
{
Console.WriteLine($"Index: {item.Index}, City: {item.Item.Name}");
}

在这两种情况下,输出结果都将与使用Index方法的示例相同。

基准测试

考虑到性能因素,我针对之前介绍的这三种不同方法,使用一个包含100,000条记录的列表进行了基准测试,你可以在下面看到测试结果:

| 方法 | 平均时间 | 误差 | 标准偏差 | 排名 |
| ---- | ---- | ---- | ---- | ---- |
| '新的Index方法' | 11.33秒 | 0.224秒 | 0.209秒 | 1 |
| '使用foreach的Select方法' | 11.51秒 | 0.202秒 | 0.189秒 | 1 |
| '使用Count的For循环方法' | 12.42秒 | 0.239秒 | 0.200秒 | 2 |

新的Index方法执行速度最快,在执行时间上略有优势,在效率方面排名最高。

使用Select结合foreach循环的方法与新的Index方法性能相当,只是在执行速度上有微小差异。

使用Countfor循环的传统方法仅比其他方法稍慢一点,性能差异较小。

Index方法允许你以一种简单且高效的方式返回列表中各项的索引位置。将该方法与其他实现相同功能的方法进行比较时,性能非常相似,但它仍稍胜一筹。如果目标是追求最高效率,即便很小的差异也很重要,特别是在处理高频访问的情况下。除此之外,这种方法还能使你的代码更简洁、更易于阅读。

如果你喜欢我的文章,请给我一个赞!谢谢

架构师老卢
资深软件架构师, 分享编程、软件设计经验, 教授前沿技术, 分享技术资源(每天发布电子书),每天进步一点点...
 最新文章