【翻译】.NET 5中的性能改进 (16)


HashSet非常类似于Dictionary<TKey, TValue>。虽然它公开了一组不同的操作(没有双关的意思),除了只存储一个键而不是一个键和一个值之外,它的数据结构基本上是相同的……或者至少过去是一样的。多年来,考虑到使用Dictionary<TKey,TValue>比HashSet多多少,我们花费了更多的努力来优化Dictionary<TKey,TValue>的实现,这两种实现已经漂移了。dotnet/corefx#40106 @JeffreyZhao移植的一些改进词典散列集,然后dotnet/runtime#37180有效地改写HashSet的实施通过re-syncing字典的(连同低堆栈移动,一些地方字典被用于一组被妥善取代)。最终的结果是HashSet最终获得了类似的收益(甚至更多,因为它是从一个更糟糕的地方开始的)。

private HashSet<int> _set = Enumerable.Range(0, 10_000).ToHashSet(); [Benchmark] public int Sum() { HashSet<int> set = _set; int sum = 0; for (int i = 0; i < 10_000; i++) if (set.Contains(i)) sum += i; return sum; } Method Runtime Mean Ratio
Sum   .NET FW 4.8   76.29 us   1.00  
Sum   .NET Core 3.1   79.23 us   1.04  
Sum   .NET 5.0   42.63 us   0.56  


类似地,dotnet/runtime#37081移植了类似的改进,从Dictionary<TKey, TValue>到ConcurrentDictionary<TKey, TValue>。

private ConcurrentDictionary<int, int> _dictionary = new ConcurrentDictionary<int, int>(Enumerable.Range(0, 10_000).Select(i => new KeyValuePair<int, int>(i, i))); [Benchmark] public int Sum() { ConcurrentDictionary<int, int> dictionary = _dictionary; int sum = 0; for (int i = 0; i < 10_000; i++) if (dictionary.TryGetValue(i, out int value)) sum += value; return sum; } Method Runtime Mean Ratio
Sum   .NET FW 4.8   115.25 us   1.00  
Sum   .NET Core 3.1   84.30 us   0.73  
Sum   .NET 5.0   49.52 us   0.43  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsssyf.html