官宣.NET 7 预览版5

打印 上一主题 下一主题

主题 608|帖子 608|积分 1824

今天我们发布了 .NET 7 预览版 5。.NET 7 的这个预览版包括对通用数学的改进,方便了 API 作者,使其更轻松,一个新的 ML.NET 文本分类 API,增加了最先进的深度学习技术 ,对于自然语言处理,对源代码生成器的各种改进以及用于 RegexGenerator 的新 Roslyn 分析器和修复器,以及在 CodeGen、可观察性、JSON 序列化/反序列化和使用流方面的多项性能改进。
您可以下载适用于 Windows、macOS 和 Linux 的 .NET 7 Preview 5。 

.NET 7 预览版 5 已通过 Visual Studio 17.3 预览版 2 进行测试。如果您想将 .NET 7 与 Visual Studio 系列产品一起使用,我们建议您使用预览频道版本。 如果您使用的是 macOS,我们建议使用最新的 Visual Studio 2022 for Mac 预览版。 现在,让我们了解此版本中的一些最新更新。

可观察性 

可观察性的目标是帮助您更好地了解应用程序在规模和技术复杂性增加时的状态。 
公开高效的 ActivityEvent 和 ActivityLink 标记枚举器方法
#68056
公开的方法可用于在性能关键场景中枚举 Tag 对象,而无需任何额外的分配和快速的项目访问。
  1. var tags = new List<KeyValuePair<string, object?>>(){    new KeyValuePair<string, object?>("tag1", "value1"),    new KeyValuePair<string, object?>("tag2", "value2"),};​ActivityLink link = new ActivityLink(default, new ActivityTagsCollection(tags));​foreach (ref readonly KeyValuePair<string, object?> tag in link.EnumerateTagObjects()){    // Consume the link tags without any extra allocations or value copying.}            ​ActivityEvent e = new ActivityEvent("SomeEvent", tags: new ActivityTagsCollection(tags));​foreach (ref readonly KeyValuePair<string, object?> tag in e.EnumerateTagObjects()){    // Consume the event's tags without any extra allocations or value copying.} 
复制代码

System.Text.Json

多态性 

#63747
System.Text.Json 现在支持使用属性注释对多态类型层次结构进行序列化和反序列化:
  1. [JsonDerivedType(typeof(Derived))]public class Base{    public int X { get; set; }}​public class Derived : Base{    public int Y { get; set; }}
复制代码
此配置为 Base 启用多态序列化,特别是在运行时类型为 Derived 时:
  1. Base value = new Derived();JsonSerializer.Serialize<Base>(value); // { "X" : 0, "Y" : 0 }
复制代码
请注意,这不会启用多态反序列化,因为有效负载将作为 Base 往返:
  1. Base value = JsonSerializer.Deserialize<Base>(@"{ ""X"" : 0, ""Y"" : 0 }");value is Derived; // false
复制代码
使用类型鉴别器
要启用多态反序列化,用户需要为派生类指定类型鉴别器:
  1. [JsonDerivedType(typeof(Base), typeDiscriminator: "base")][JsonDerivedType(typeof(Derived), typeDiscriminator: "derived")]public class Base{    public int X { get; set; }}​public class Derived : Base{    public int Y { get; set; }}
复制代码
现在将发出 JSON 以及类型鉴别器元数据:
  1. Base value = new Derived();JsonSerializer.Serialize<Base>(value); // { "$type" : "derived", "X" : 0, "Y" : 0 }
复制代码
可用于多态反序列化值:
  1. Base value = JsonSerializer.Deserialize<Base>(@"{ ""$type"" : ""derived"", ""X"" : 0, ""Y"" : 0 }");value is Derived; // true
复制代码
类型鉴别器标识符也可以是整数,因此以下形式是有效的:
  1. [JsonDerivedType(typeof(Derived1), 0)][JsonDerivedType(typeof(Derived2), 1)][JsonDerivedType(typeof(Derived3), 2)]public class Base { }​JsonSerializer.Serialize<Base>(new Derived2()); // { "$type" : 1, ... }
复制代码
▌Utf8JsonReader.CopyString
#54410
直到今天,Utf8JsonReader.GetString() 一直是用户使用解码后的 JSON 字符串的唯一方式。这将始终分配一个新字符串,这可能不适合某些性能敏感的应用程序。新包含的 CopyString 方法允许将未转义的 UTF-8 或 UTF-16 字符串复制到用户拥有的缓冲区:
  1. int valueLength = reader.HasReadOnlySequence ? checked((int)ValueSequence.Length) : ValueSpan.Length;char[] buffer = ArrayPool<char>.Shared.Rent(valueLength);int charsRead = reader.CopyString(buffer);ReadOnlySpan<char> source = buffer.Slice(0, charsRead);​ParseUnescapedString(source); // handle the unescaped JSON stringArrayPool<char>.Shared.Return(buffer);
复制代码
或者如果处理 UTF-8 更可取:
  1. ReadOnlySpan<byte> source = stackalloc byte[0];if (!reader.HasReadOnlySequence && !reader.ValueIsEscaped){    source = reader.ValueSpan; // No need to copy to an intermediate buffer if value is span without escape sequences}else{    int valueLength = reader.HasReadOnlySequence ? checked((int)ValueSequence.Length) : ValueSpan.Length;    Span<byte> buffer = valueLength <= 256 ? stackalloc byte[256] : new byte[valueLength];    int bytesRead = reader.CopyString(buffer);    source = buffer.Slice(0, bytesRead);}​ParseUnescapedBytes(source);
复制代码

ML.NET 文本分类 API

文本分类是将标签或类别应用于文本的过程。
常见用例包括:


  • 将电子邮件分类为垃圾邮件或非垃圾邮件
  • 从客户评论中分析情绪是积极的还是消极的
  • 应用标签来支持工单
文本分类是分类的一个子集,因此今天您可以使用 ML.NET 中现有的分类算法来解决文本分类问题。然而,这些算法并没有解决文本分类以及现代深度学习技术的常见挑战。
我们很高兴推出 ML.NET 文本分类 API,该 API 使您可以更轻松地训练自定义文本分类模型,并将用于自然语言处理的最新最先进的深度学习技术引入 ML.NET。
有关更多详细信息,请参阅我们的 ML.NET 特定公告

代码生成

非常感谢社区贡献者。
@singleaccretion 在预览版 5 期间做出了 23 项 PR 贡献,其中亮点是:
改进冗余分支优化以处理更多副作用 #68447
PUTARG_STK/x86: 标记 push [mem] 候选 reg 可选 #68641
在 LCL_FLD 上复制传播 #68592
@Sandreenko 完成允许 StoreLclVar src 成为 IND/FLD #59315@hez2010 修复了 #68475 中的 CircleInConvex 测试。
来自@anthonycanino@aromaa@ta264 的更多贡献包含在后面的部分中
Arm64
#68363 合并“msub”(将两个寄存器值相乘,从第三个寄存器值中减去乘积)和“madd”(将两个寄存器值相乘,添加第三个寄存器值)逻辑。
Arm64:让 CpBlkUnroll 和 InitBlkUnroll 使用 SIMD 寄存器来初始化复制小于 128 字节的内存块(请参阅性能改进细节)。

循环优化
#67930 处理循环克隆的更多场景现在支持以 > 1 的增量向后或向前的循环(请参阅性能改进详细信息)。

#68588 提升“this”对象的空值检查将空值检查移动到循环外的对象上(请参阅性能改进细节)。


x86/x64 优化 




一般优化



  • PR#68105 启用了多个嵌套的“no GC”区域请求。
  • PR#69034 删除了“提升参数”尾调用限制。
现代化 JIT

随着社区增加了对 JIT 代码库的贡献,重组和现代化我们的代码库以使我们的贡献者能够轻松地增加和快速开发代码变得非常重要。 
在 Preview 5 中,我们在内部做了大量工作,清理了 JIT 的中间表示,并消除了过去设计决策带来的限制。在许多情况下,这项工作导致 JIT 本身的内存使用更少和吞吐量更高,而在其他情况下,它导致了更好的代码质量。以下是一些亮点:

以上允许我们在使用 byte/sbyte/short/ushort 类型的参数内联函数时消除 JIT 内联中的旧限制,从而提高代码质量(允许内联替换小参数 #69068
需要改进的一个领域是更好地理解涉及读取和写入结构和结构字段的不安全代码。 @SingleAccretion 通过将 JIT 的内部模型转换为更通用的“物理”模型,在这一领域做出了巨大的改变。这为 JIT 使用 struct reinterpretation 等功能更好地推理不安全代码铺平了道路:


  • 物理值编号 #68712
  • 为 VNF_BitCast 实现常量折叠 #68979
还进行了其他小的清理以简化 JIT IR:


  • 删除 GTF_LATE_ARG #68617
  • 在内联候选参数中替换 GT_RET_EXPR #69117
  • 在 LIR #68460 中删除存储作为调用的操作数

启用库修剪

正如我们之前所描述的,修剪让 SDK 从您的自包含应用程序中删除未使用的代码,以使它们更小。但是,修剪警告可能表明应用程序与修剪不兼容。为了使应用程序兼容,它们的所有引用也必须兼容。
为此,我们需要库也采用修剪。在预览版 5 中,我们努力使用 Roslyn 分析器更轻松地查找和修复库中的修剪警告。要查看库的修剪警告,请将 true 添加到项目文件中。修复警告后,使用您的库修剪的应用程序将更小并且与修剪兼容。请参阅准备 .NET 库以进行修剪 - .NET | Microsoft Docs 了解有关库修剪的更多信息。

面向 .NET 7

要面向 .NET 7,您需要在项目文件中使用 .NET 7 Target Framework Moniker (TFM)。例如: 
  1. [JsonSerializable(typeof(typeof(MyPoco))]public class MyContext : JsonSerializerContext {}​public class MyPoco{    // Use of IAsyncEnumerable that previously resulted     // in JsonSerializer.Serialize() throwing NotSupportedException     public IAsyncEnumerable<int> Data { get; set; } }​// It now works and no longer throws NotSupportedExceptionJsonSerializer.Serialize(new MyPoco { Data = ... }, MyContext.MyPoco); 
复制代码
全套 .NET 7 TFM,包括特定于操作的 TFM。


  • [JsonSerializable(typeof(typeof(MyPoco))]public class MyContext : JsonSerializerContext {}​public class MyPoco{    // Use of IAsyncEnumerable that previously resulted     // in JsonSerializer.Serialize() throwing NotSupportedException     public IAsyncEnumerable<int> Data { get; set; } }​// It now works and no longer throws NotSupportedExceptionJsonSerializer.Serialize(new MyPoco { Data = ... }, MyContext.MyPoco); 
  • [JsonSerializable(typeof(typeof(MyPoco))]public class MyContext : JsonSerializerContext {}​public class MyPoco{    // Use of IAsyncEnumerable that previously resulted     // in JsonSerializer.Serialize() throwing NotSupportedException     public IAsyncEnumerable<int> Data { get; set; } }​// It now works and no longer throws NotSupportedExceptionJsonSerializer.Serialize(new MyPoco { Data = ... }, MyContext.MyPoco); -安卓
  • [JsonSerializable(typeof(typeof(MyPoco))]public class MyContext : JsonSerializerContext {}​public class MyPoco{    // Use of IAsyncEnumerable that previously resulted     // in JsonSerializer.Serialize() throwing NotSupportedException     public IAsyncEnumerable<int> Data { get; set; } }​// It now works and no longer throws NotSupportedExceptionJsonSerializer.Serialize(new MyPoco { Data = ... }, MyContext.MyPoco); -ios
  • [JsonSerializable(typeof(typeof(MyPoco))]public class MyContext : JsonSerializerContext {}​public class MyPoco{    // Use of IAsyncEnumerable that previously resulted     // in JsonSerializer.Serialize() throwing NotSupportedException     public IAsyncEnumerable<int> Data { get; set; } }​// It now works and no longer throws NotSupportedExceptionJsonSerializer.Serialize(new MyPoco { Data = ... }, MyContext.MyPoco); -maccatalyst
  • [JsonSerializable(typeof(typeof(MyPoco))]public class MyContext : JsonSerializerContext {}​public class MyPoco{    // Use of IAsyncEnumerable that previously resulted     // in JsonSerializer.Serialize() throwing NotSupportedException     public IAsyncEnumerable<int> Data { get; set; } }​// It now works and no longer throws NotSupportedExceptionJsonSerializer.Serialize(new MyPoco { Data = ... }, MyContext.MyPoco); -macos
  • [JsonSerializable(typeof(typeof(MyPoco))]public class MyContext : JsonSerializerContext {}​public class MyPoco{    // Use of IAsyncEnumerable that previously resulted     // in JsonSerializer.Serialize() throwing NotSupportedException     public IAsyncEnumerable<int> Data { get; set; } }​// It now works and no longer throws NotSupportedExceptionJsonSerializer.Serialize(new MyPoco { Data = ... }, MyContext.MyPoco); -tvos
  • [JsonSerializable(typeof(typeof(MyPoco))]public class MyContext : JsonSerializerContext {}​public class MyPoco{    // Use of IAsyncEnumerable that previously resulted     // in JsonSerializer.Serialize() throwing NotSupportedException     public IAsyncEnumerable<int> Data { get; set; } }​// It now works and no longer throws NotSupportedExceptionJsonSerializer.Serialize(new MyPoco { Data = ... }, MyContext.MyPoco); -windows
我们希望从 .NET 6 升级到 .NET 7 应该很简单。请报告您在使用 .NET 7 测试现有应用程序的过程中发现的任何重大更改。

支持

.NET 7 是一个短期支持 (STS) 版本,这意味着它将在发布之日起 18 个月内获得免费支持和补丁。需要注意的是,所有版本的质量都是相同的。唯一的区别是支撑的长度。有关 .NET 支持政策的更多信息,请参阅 .NET 和 .NET Core 官方支持政策
我们最近将“Current当前”名称更改为“短期支持 (STS)”。我们正在推出这一变化

重大变化

您可以通过阅读 .NET 7 中的重大更改文档找到最新的 .NET 7 重大更改列表。它按区域和版本列出了重大更改,并附有详细说明的链接。
要查看提出了哪些重大更改但仍在审核中,请关注 Proposed .NET Breaking Changes GitHub 问题

路线图

.NET 版本包括产品、库、运行时和工具,代表了 Microsoft 内外多个团队之间的协作。您可以通过阅读产品路线图了解有关这些领域的更多信息:

我们感谢您对 .NET 的所有支持和贡献。请尝试 .NET 7 Preview 5 并告诉我们您的想法!

查看.NET 7 预览版5
关注微软中国MSDN公众号了解更多

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

玛卡巴卡的卡巴卡玛

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表