【分享】C#集合数据去重的5种方式及其性能对比测试分析

360影视 2025-01-03 20:13 3

摘要:今天我们一起来讨论一下关于C#集合数据去重的5种方式并且使用BenchmarkDotNet对这5种方式进行性能基准对比测试分析,每种方法都有其特点和适用场景,我们可以根据具体需求和执行效率选择一种进行使用。

今天我们一起来讨论一下关于C#集合数据去重的5种方式并且使用BenchmarkDotNet对这5种方式进行性能基准对比测试分析,每种方法都有其特点和适用场景,我们可以根据具体需求和执行效率选择一种进行使用。

BenchmarkDotNet是一个基于.NET开源、功能全面、易于使用的性能基准测试框架,它为.NET开发者提供了强大的性能评估和优化能力。通过自动化测试、多平台支持、高级统计分析和自定义配置等特性,BenchmarkDotNet帮助开发者更好地理解和优化软件系统的性能表现。

使用详细介绍:
使用 BenchmarkDotNet 对 .NET 代码进行性能基准测试

C# 中的 HashSet 是一种集合类型,它确保其中的元素是唯一的,不允许重复值的存在。当你尝试向 HashSet 中添加一个重复的元素时,HashSet 会忽略重复的值,而不会引发错误。这使得 HashSet 成为一个非常方便的数据结构,用于存储一组唯一的元素,并且在需要时可以高效地进行查找、插入和删除操作,注意HashSet中的元素是无序的。

/// /// 使用HashSet去重/// TODO:HashSet是一个集合类,它的特点是不允许重复元素,可以方便地实现去重功能。/// public static void HashSetDuplicate{var dataSource = new List { 1, 2, 3, 2, 5, 88, 99, 99, 100, 88, 30, 50, 15, 100, 99, 99, 2, 3 };HashSet uniqueData = new HashSet(dataSource);Console.WriteLine(string.Join(", ", uniqueData));} /// /// 直接循环遍历去重/// public static void LoopTraversalDuplicate{var dataSource = new List { 1, 2, 3, 2, 5, 88, 99, 99, 100, 88, 30, 50, 15, 100, 99, 99, 2, 3 };var uniqueData = new List;foreach (var item in dataSource){//if (!uniqueData.Any(x => x == item))//if (!uniqueData.Exists(x => x == item))if (!uniqueData.Contains(item)){uniqueData.Add(item);}}Console.WriteLine(string.Join(", ", uniqueData));}

Linq中的Distinct方法用于从集合中筛选出不重复的元素。Distinct方法基于元素的相等性来进行筛选,并返回一个包含不重复元素的新序列。底层实现还是使用到了HashSet。

/// /// 使用Linq的Distinct方法去重/// public static void DistinctDuplicate{var dataSource = new List { 1, 2, 3, 2, 5, 88, 99, 99, 100, 88, 30, 50, 15, 100, 99, 99, 2, 3 };var uniqueData = dataSource.Distinct.ToList;Console.WriteLine(string.Join(", ", uniqueData));}

GroupBy方法将原始集合中的元素进行分组,根据指定的键或条件进行分组。每个分组都会有一个唯一的键,通过将原始集合分组并选择每个分组中的第一个元素,实现了去重的效果。

/// /// 使用Linq的GroupBy方法去重/// public static void GroupByDuplicate{var dataSource = new List { 1, 2, 3, 2, 5, 88, 99, 99, 100, 88, 30, 50, 15, 100, 99, 99, 2, 3 };//GroupBy方法将原始集合中的元素进行分组,根据指定的键或条件进行分组。每个分组都会有一个唯一的键,通过将原始集合分组并选择每个分组中的第一个元素,实现了去重的效果。var uniqueData = dataSource.GroupBy(item => item).Select(group => group.First).ToList;Console.WriteLine(string.Join(", ", uniqueData));} /// /// 使用自定义的比较器和循环遍历/// public static void CustomEqualityComparerDuplicate{var dataSource = new List { 1, 2, 3, 2, 5, 88, 99, 99, 100, 88, 30, 50, 15, 100, 99, 99, 2, 3 };var uniqueData = new List;foreach (var item in dataSource){if (!uniqueData.Contains(item, new CustomEqualityComparer)){uniqueData.Add(item);}}Console.WriteLine(string.Join(", ", uniqueData));}/// /// 自定义的比较器/// public class CustomEqualityComparer : IEqualityComparer{public bool Equals(int x, int y){return x == y;}public int GetHashCode(int obj){return obj.GetHashCode;}}

接下来我们使用BenchmarkDotNet对这5种集合去重的方式进行性能基准对比测试分析。

using BenchmarkDotNet.Attributes;namespace BenchmarkDotNetExercise{[MemoryDiagnoser]//记录内存分配情况public class DataSetDeduplicationBenchmark{private List dataSource;public DataSetDeduplicationBenchmark{// 生成大量重复数据 dataSource = Enumerable.Repeat(Enumerable.Range(1, 100), 10000).SelectMany(x => x).ToList;}/// /// 使用HashSet去重/// TODO:HashSet是一个集合类,它的特点是不允许重复元素,可以方便地实现去重功能。/// [Benchmark]public void HashSetDuplicate{HashSet uniqueData = new HashSet(dataSource);}/// /// 直接循环遍历去重/// [Benchmark]public void LoopTraversalDuplicate{var uniqueData = new List;foreach (var item in dataSource){//if (!uniqueData.Any(x => x == item))//if (!uniqueData.Exists(x => x == item))if (!uniqueData.Contains(item)){uniqueData.Add(item);}}}/// /// 使用Linq的Distinct方法去重/// [Benchmark]public void DistinctDuplicate{var uniqueData = dataSource.Distinct.ToList;}/// /// 使用Linq的GroupBy方法去重/// [Benchmark]public void GroupByDuplicate{//GroupBy方法将原始集合中的元素进行分组,根据指定的键或条件进行分组。每个分组都会有一个唯一的键,通过将原始集合分组并选择每个分组中的第一个元素,实现了去重的效果。var uniqueData = dataSource.GroupBy(item => item).Select(group => group.First).ToList;}/// /// 使用自定义的比较器和循环遍历/// [Benchmark]public void CustomEqualityComparerDuplicate{var uniqueData = new List;foreach (var item in dataSource){if (!uniqueData.Contains(item, new CustomEqualityComparer)){uniqueData.Add(item);}}}/// /// 自定义的比较器/// public class CustomEqualityComparer : IEqualityComparer{public bool Equals(int x, int y){return x == y;}public int GetHashCode(int obj){return obj.GetHashCode;}}}}分析生成的报告MethodMeanErrorStdDevGen0Gen1Gen2AllocatedHashSetDuplicate7.043 ms0.0546 ms0.0511 ms343.7500343.7500343.750018169.63 KBLoopTraversalDuplicate7.385 ms0.0309 ms0.0274 ms---1.16 KBDistinctDuplicate7.034 ms0.0497 ms0.0465 ms343.7500343.7500343.750018170.1 KBGroupByDuplicate12.685 ms0.1025 ms0.0958 ms2265.62501781.2500515.625012843.65 KBCustomEqualityComparerDuplicate25.608 ms0.1826 ms0.1708 ms3812.5000--23438.68 KB

说明:

Mean: 所有测量值的算术平均值。Error: 99.9% 置信区间的一半。StdDev: 所有测量值的标准差。Gen0: 第 0 代 GC 每 1000 次操作收集一次。Gen1: 第 1 代 GC 每 1000 次操作收集一次。Gen2: 第 2 代 GC 每 1000 次操作收集一次。Allocated: 每次操作分配的内存(仅托管内存,包含所有内容,1KB = 1024B)。1 ms: 1 毫秒(0.001 秒)。

欢迎点赞+转发+关注!大家的支持是我分享最大的动力!!!

来源:IT技术资源爱好者

相关推荐