当然不要忘记,官网才是最好的老师:docs.microsoft.com/zh-cn/dotnet/core/
沙盒学习指南: 免费环境docs.microsoft.com/zh-cn/learn/browse
posted @ 2020 初久的私房菜 推荐出品

.NET 关于 Frozen Collections

 

正文

介绍

.NET 8 引入了 Frozen Collections,这是对已有不可变(Immutable)和只读(ReadOnly)集合的补充。那么,Frozen Collections 有什么独特之处呢?本文将探讨 Frozen Collections 的特点、优势以及适用场景。

Frozen Collections 简介

.NET 8 引入了两种新的抽象类型:FrozenSet<T>FrozenDictionary<TKey, TValue>。这些类型不能直接实例化,但可以通过扩展方法来创建。

以下是如何创建 Frozen Collections 的示例:

Dictionary<int, string> dictionary = [];
dictionary.Add(1, "One");
dictionary.Add(2, "Two");

FrozenSet<int> frozenNumbers = numbers.ToFrozenSet();
FrozenDictionary<int, string> frozenDict = dictionary.ToFrozenDictionary();

一旦集合被冻结,你就不能修改其值。

Frozen Collections 的优势

Frozen Collections 的关键优势在于它们针对快速查找和枚举进行了优化。然而,创建 Frozen Collections 的成本相对较高。

因此,Frozen Collections 最适合于集合创建不频繁,但在运行时频繁使用的场景。

接下来,我们将通过性能测试来验证这一点。

在继续之前,我想指出 ReadOnly 集合与不可变和 Frozen 集合之间的一个重要区别。

观察以下代码:


FrozenSet<int> frozenNumbers = numbers.ToFrozenSet();
ImmutableList<int> immutableNumbers = numbers.ToImmutableList();
ReadOnlyCollection<int> readOnlyNumbers = numbers.AsReadOnly();

numbers.Add(6);

Console.WriteLine($"Frozen: {string.Join(", ", frozenNumbers)}");
Console.WriteLine($"Immutable: {string.Join(", ", immutableNumbers)}");
Console.WriteLine($"ReadOnly: {string.Join(", ", readOnlyNumbers)}");
// Frozen: 1, 2, 3, 4, 5
// Immutable: 1, 2, 3, 4, 5
// ReadOnly: 1, 2, 3, 4, 5, 6

ReadOnly 集合是现有集合的包装器。你不能修改包装器,但可以修改现有的集合。

性能测试:查找操作

接下来,我们来测试不同集合的查找性能。

我使用了著名的 BenchmarkDotNet 工具。

测试设置如下:

public int CollectionSize { get; set; }

private List<int> _list;
private ImmutableList<int> _immutableList;
private HashSet<int> _hashSet;
private FrozenSet<int> _frozenSet;

[GlobalSetup]
public void SetUp()
{
    _list = Enumerable.Range(0, CollectionSize).ToList();
    _immutableList = Enumerable.Range(0, CollectionSize).ToImmutableList();
    _hashSet = Enumerable.Range(0, CollectionSize).ToHashSet();
    _frozenSet = Enumerable.Range(0, CollectionSize).ToFrozenSet();
}

我添加了 HashSet 作为对比。测试的集合大小分别为 100、1000 和 10000 个元素。

测试代码如下:

public void LookupList()
{
    for (var i = 0; i < CollectionSize; i++)
        _ = _list.Contains(i);
}

[Benchmark]
public void LookupImmutableList()
{
    for (var i = 0; i < CollectionSize; i++)
        _ = _immutableList.Contains(i);
}

[Benchmark]
public void LookupHashSet()
{
    for (var i = 0; i < CollectionSize; i++)
        _ = _hashSet.Contains(i);
}

[Benchmark]
public void LookupFrozenSet()
{
    for (var i = 0; i < CollectionSize; i++)
        _ = _frozenSet.Contains(i);
}

测试结果表明,FrozenSet 的查找性能甚至优于 HashSet

性能测试:创建操作

接下来,我们来测试 FrozenSet 的创建成本。

测试代码如下:

{
    private readonly int[] Numbers = Enumerable.Range(0, 1000).ToArray();

    [Benchmark(Baseline = true)]
    public List<int> ToList() => Numbers.ToList();

    [Benchmark]
    public FrozenSet<int> ToFrozenSet() => Numbers.ToFrozenSet();

    [Benchmark]
    public HashSet<int> ToHashSet() => Numbers.ToHashSet();
}

测试结果表明,FrozenSet 的创建成本较高。

总结

通过本文的介绍和性能测试,我们了解到 Frozen Collections 是不可变且只读的,针对快速查找和枚举进行了优化。它们最适合于集合创建不频繁,但在运行时频繁使用的场景,例如长期运行的服务。

posted @   初久的私房菜  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
历史上的今天:
2023-02-21 .Net6 + GraphQL + MongoDb拦截器
2022-02-21 关于Code Review
2022-02-21 使用 dotnet watch 时包含 CSHTML 文件
2022-02-21 记一次公司项目缓存击穿
2022-02-21 C# 9 特性二
2022-02-21 C# 9 特性三
作者:初久的私房菜
好好学习,天天向上
返回顶部小火箭
好友榜:
如果愿意,把你的博客地址放这里
张弛:https://blog.zhangchi.fun/
点击右上角即可分享
微信分享提示