.NET 8 预览版 1 发布!
.NET 8 是一个长期支持(LTS) 版本。这篇文章涵盖了推动增强功能优先级排序和选择开发的主要主题和目标。.NET 8 预览版和发布候选版本将每月交付一次。像往常一样,最终版本将在 11 月的某个时候在 .NET Conf 上发布。
.NET 版本包括产品、库、运行时和工具,代表 Microsoft 内外多个团队之间的协作。这篇博文中涵盖的更广泛的主题并不包含 .NET 8 的所有关键场景和投资。它们代表了很大的领域,但只是进入 .NET 8 的所有重要工作的一部分。我们计划对 ASP.NET Core, Blazor, EF Core, WinForms, WPF 和其他平台进行广泛的投资。
欢迎使用 .NET 8
去年年底,我们发布了 .NET 7,这是 .NET 团队与支持该版本的令人惊叹的社区合作的结果,该版本有10,000多名社区成员提供了超过28,000个社区贡献。.NET 7 是当今构建应用程序的首选框架。该版本将平台与对 ARM64 的原生支持和对 Linux 的增强支持统一起来。它有助于通过 .NET MAUI 等工具使您的应用程序现代化,这些工具可以从同一代码库构建跨平台的移动和桌面应用程序。它包括对 API 性能的改进,并使构建和部署分布式云原生应用程序变得更加容易。. NET 7 通过改进 C# 11 减少了必要的代码量,简化了构建应用程序的体验,并使得仅用几行代码就可以创建和配置 API。从帮助调试云 API 集成到直接从 .NET SDK 构建容器的开发隧道,对工具进行了大量改进,帮助开发人员提高工作效率。
我们将在整个版本中更新 .NET 8 中的新增功能。
您可以通过向下滚动阅读我们在预览1中发布的内容。首先,让我们展望一下 .NET 8 的愿景。
云原生开发者的最佳平台和工具
我们相信 .NET 开发人员应该能够将他们的应用程序快速迁移到云中,在不影响性能的情况下扩展他们的应用程序,并根据可操作的数据和关于您的应用程序在生产中的反馈来改进他们的应用程序。我们将投资于通过持续集成和部署更轻松地管理本地开发和测试的完整端到端体验。我们的目标是让微服务架构的实施以及容器的构建和部署变得更加容易。
云原生是一个术语,用于描述专门为在云计算环境中部署而构建的应用程序的架构和设计。云原生背后的主要思想是利用云计算平台提供的优势,例如可扩展性、弹性和自我修复,来创建高度可扩展和有弹性的应用程序。这提供了灵活性,并避免了为支持增长而对硬件和软件进行潜在的过度投资。许多开发人员将云原生与微服务、容器编排 (Kubernetes) 和“即服务”产品等概念联系在一起。
使用 MAUI 和 Blazor 混合进行跨平台移动和桌面开发的绝佳体验
在 .NET 7 期间,我们发布了 .NET 多平台应用程序用户界面 (MAUI) SDK 和 Visual Studio 工具支持。.NET MAUI 提供了一个框架,用于使用单个 C# 代码库为运行 Android、iOS、macOS 和 Windows 的移动和桌面设备创建本机应用程序。除了支持 XAML UI 之外,您还可以使用 Blazor 构建具有 Razor UI 组件的混合应用程序,这些应用程序可以访问本机设备平台并在移动、桌面和 Web 之间共享。.NET 团队计划以这些经验为基础,专注于提高 SDK 和工具的质量、稳定性、性能和集成度。
势头:根据您的意见继续关注质量和性能
.NET 的每个版本都包括对 API、库和框架的性能、质量、稳定性和易用性的改进,它们构成了活跃且不断发展的 .NET 生态系统。其中许多改进是由客户和社区成员确定并优先考虑的。.NET 8 将遵循相同的趋势,依靠您高度重视的反馈来帮助指导我们的愿景并推动我们的重点。
了解最新情况并保持最新状态
.NET 升级帮助是一个有价值的工具,可以帮助开发人员将他们的应用程序从旧版本的 .NET Framework 迁移到新版本。该工具的最新版本具有改进的功能,可以支持新场景并处理更多案例。有了这个工具,开发人员现在可以轻松地将他们的应用程序升级到 .NET 6或 .NET 7。
该工具可以自动检测并建议需要对代码进行的更改,以确保与较新版本的框架兼容。此外,它还可以处理更复杂的场景,例如升级使用第三方库的应用程序以及与更新的平台功能集成。这些改进使 .NET 升级辅助成为那些希望保持其应用程序最新并利用最新的 .NET 功能的开发人员的不可或缺的工具。该工具最近作为 Visual Studio 扩展引入。可帮助您从舒适的 Visual Studio 升级。
以 .NET 8 为目标
要以 .NET 8 为目标,您首先需要确保从 Microsoft 官方网站安装了 .NET 8 SDK。接下来,您可以创建一个新项目,并通过在项目设置中设置适当的目标框架来指定您希望以 .NET 8 为目标。
您还可以通过更改项目属性中的目标框架,将现有项目更新为面向 .NET 8。为此,请在 Visual Studio 或您喜欢的 IDE 中右键单击项目,选择“属性”,然后选择“应用程序”选项卡。从那里,您可以选择要使用的目标框架版本。这将设置适当的目标框架:
<TargetFramework>net8.0</TargetFramework>
请记住,以 .NET 8 为目标可能需要更改您的代码或依赖项,因为 API 或其他功能可能与以前版本的 .NET 有所不同。最好查看 .NET 8 的文档和发行说明,以确保您的代码和依赖项与新版本兼容。
.NET 8 预览版 1 中的新增功能
我们的第一个预览版包含您今天就可以试用的新功能。以下是预期结果的摘要。有关详细的发行说明和重大更改,请阅读 .NET 8 中的新增功能。
Native AOT
第一个 NativeAOT 功能在 .NET 7 和目标控制台应用程序中发布。Ahead-of-Time (AOT)编译是 .NET 中的一项重要功能,可以对 .NET 应用程序的性能产生重大影响。感谢 Adeel 和 Filip 将 NativeAOT 功能引入 macOS 进行预览 1。.NET 团队将专注于完善 .NET 8 的一些基础知识,例如大小(请参阅dotnet/runtime#79003)。使用 NativeAOT 发布应用程序会创建一个完全独立的应用程序版本,不需要单独的运行时,因为所有内容都包含在单个文件中。从预览版1开始,这个文件变小了。事实上,Linux 版本现在最多缩小了 50%。
以下是包含整个 .NET 运行时的 Native AOT 的“Hello, World”应用程序的大小:
NativeAOT 将继续扩展并瞄准 .NET 8 中的其他应用场景,因此请继续关注此博客以获取未来更新!
如果您不熟悉 AOT,这里有一些 AOT 提供的好处:
- 减少内存占用:与 JIT 编译代码相比,AOT 编译代码需要更少的内存,因为 JIT 编译器生成 AOT 编译应用程序不需要的中间代码。这对于内存有限的设备尤其有益,例如嵌入式系统和移动设备。
- 改进的启动时间:与 JIT 编译代码相比,AOT 编译代码启动速度更快,因为它消除了 JIT 编译器生成中间代码并针对特定硬件和软件环境优化代码的需要。这对于必须快速启动的应用程序尤其有利,例如系统服务、无服务器“功能”和后台任务。
- 延长电池寿命:与 JIT 编译代码相比,AOT 编译代码消耗的电量更少,因为它消除了 JIT 编译器生成中间代码并针对特定硬件和软件环境优化代码的需要。这对于依赖电池的设备(例如移动设备)尤其有益。
.NET 容器镜像
.NET 开发人员可以使用容器镜像以轻量级、可移植的格式打包和部署他们的应用程序,这种格式可以在不同环境中运行并且可以轻松部署到云端中。关于如何将容器镜像用于 .NET 应用程序,预览版 1 做出了以下改进:
- 将默认 Linux 发行版更新为 Debian 12:.NET 容器镜像现在使用 Debian 12 (Bookworm),我们预计将在 2023 年年中发布。Debian 用于方便的标签,8.0如8.0-bookworm-slim。
- 标签更改:.NET 8 预览容器镜像将使用8.0-preview 作为标签(不是8.0)并在 Release Candidate 版本过渡到8.0。这种方法的目标是更清楚地描述预览版。这是根据社区请求进行的更改。
- 与非根(non-root)用户一起运行容器镜像:尽管容器基础镜像几乎总是配置为与根用户一起运行——这种设置往往会保留在生产环境中——但它并不总是最好的方法。然而,将每个应用程序配置为拥有不同的用户是一件很痛苦的事情,而且容器镜像不会附带适合容器工作负载的非根用户。
.NET 8 提供了一种更好的方法。从预览版 1 开始,我们发布的所有容器镜像都将支持非根配置。以下是用于以非根身份为 Dockerfiles 运行容器的单行示例:
USER app
此外,您现在可以使用 -u app。默认端口已从端口80更改为8080。这是启用非根方案所必需的重大更改,因为端口80是特权端口。
运行时和库
处理随机性的实用方法
System.Random 和 System.Security.Cryptography.RandomNumberGenerator 都有实用方法 GetItems 以用于从输入集中随机选择项目(“用替换”),以及用于随机化跨度顺序的实用方法 Shuffle。
Shuffle 有助于减少机器学习中的训练偏差(因此第一件事并不总是训练,最后一件事总是测试):
YourType[] trainingData = LoadTrainingData();
Random.Shared.Shuffle(trainingData);IDataView sourceData = mlContext.Data.LoadFromEnumerable(trainingData);DataOperationsCatalog.TrainTestData split = mlContext.Data.TrainTestSplit(sourceData);
model = chain.Fit(split.TrainSet);IDataView predictions = model.Transform(split.TestSet);
...
我们玩个游戏好吗?玩西蒙游戏怎么样?
private static ReadOnlySpan<Button> s_allButtons = new[]
{Button.Red,Button.Green,Button.Blue,Button.Yellow,
};...Button[] thisRound = Random.Shared.GetItems(s_allButtons, 31);
// rest of game goes here ...
System.Numerics 和 System.Runtime.Intrinsics
在可能的情况下,我们将 Vector256<T> 重新实现为内部 2x Vector128<T> ops:dotnet/runtime#76221。这能使一些函数部分加速,例如在 Arm64 上 Vector128.IsHardwareAccelerated == true 但 Vector256.IsHardwareAccelerated == false。
我们添加了 Vector512<T> 初始托管实现:dotnet/runtime#76642。与之前的工作项非常相似,这在内部实现为 2x Vector256<T> ops(因此间接实现为 4x Vector128 ops)。这能使一些函数部分加速,即使 Vector512.IsHardwareAccelerated == false 注意:Vector512 还没有直接加速,即使底层硬件支持它也是如此。此类功能应在未来的预览版中启用。
重写 Matrix3x2 和 Matrix4x4 以更好地利用硬件加速:dotnet/runtime#80091。这能使某些基准测试的性能提升高达 48 倍。6-10倍的改进更为常见。
注意:预览版2会对 Quaternion 和 Plane 进行改进。
Hardware Intrinsics 现在用 ConstExpected 属性进行注释:dotnet/runtime#80192。这能确保用户知道底层硬件何时需要常量,因此非常量值何时可能会意外损害性能。
将 Lerp API 添加到 IFloatingPointIeee754<TSelf> 从而添加到 float (System.Single), double (System.Double)和 System.Half和: dotnet/runtime#81186。这能有效且正确地执行两个值之间的线性插值。
JSON 改进
我们不断改进 System.Text.Json,专注于增强源代码生成器在 NativeAOT 应用程序中与 ASP.NET Core 一起使用时的性能和可靠性。下表显示了预览版 1 附带的新功能:
- 缺少成员处理 dotnet/runtime#79945
现在可以配置对象反序列化行为,底层 JSON 负载包含无法映射到反序列化 POCO 类型成员的属性时都可以适用。这可以通过设置一个 JsonUnmappedMemberHandling 值来控制,也可以作为 POCO 类型本身的注释,全局上 JsonSerializerOptions 或通过自定义 JsonTypeInfo 相关类型的合同以编程方式进行控制:
JsonSerializer.Deserialize<MyPoco>("""{"Id" : 42, "AnotherId" : -1 }""");
// JsonException : The JSON property 'AnotherId' could not be mapped to any .NET member contained in type 'MyPoco'.[JsonUnmappedMemberHandling(JsonUnmappedMemberHandling.Disallow)]
public class MyPoco
{public int Id { get; set; }
}
- 源生成器支持 required 和 init 属性 dotnet/runtime#79828
源生成器现在支持序列化具有 required 和 init 属性的类型,正如当前在基于反射的序列化中所支持的那样。 - 接口层次结构支持 dotnet/runtime#78788
System.Text.Json 现在支持从接口层次结构序列化属性:
IDerived value = new Derived { Base = 0, Derived =1 };
JsonSerializer.Serialize(value); // {"Base":0,"Derived":1}public interface IBase
{public int Base { get; set; }
}public interface IDerived : IBase
{public int Derived { get; set; }
}public class Derived : IDerived
{public int Base { get; set; }public int Derived { get; set; }
}
- Snake Case 和 Kebab Case dotnet/runtime#69613
该库现在附带了 snake_case 的命名策略和 kebab-case 属性名称转换。它们的用法与现有的 camelCase 命名策略类似:
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower };
JsonSerializer.Serialize(new { PropertyName = "value" }, options); // { "property_name" : "value" }
现在可以使用以下命名策略:
namespace System.Text.Json;public class JsonNamingPolicy
{public static JsonNamingPolicy CamelCase { get; }public static JsonNamingPolicy KebabCaseLower { get; }public static JsonNamingPolicy KebabCaseUpper { get; }public static JsonNamingPolicy SnakeCaseLower { get; }public static JsonNamingPolicy SnakeCaseUpper { get; }
}
感谢 @YohDeadfall 贡献了实施。
- 添加 JsonSerializer.MakeReadOnly() 和 IsReadOnly API dotnet/runtime#74431JsonSerializerOptions 类一直使用可冻结语义,但直到现在冻结只能通过将实例传递给其中一种 JsonSerializer 方法来隐式完成。添加新 API 后,用户可以明确控制何时 JsonSerializerOptions 应冻结其实例:
public class MySerializer
{private JsonSerializerOptions Options { get; }public MySerializer(){Options = new JsonSerializerOptions(JsonSerializerDefaults.Web) { Converters = { new MyCustomConverter() } };Options.MakeReadOnly(); // Make read-only before exposing the property.}
}
核心库中以性能为中心的全新类型
多个新类型已添加到核心库中,开发人员能够利用新类型在常见场景中提高代码的性能。
新的命名空间 System.Collections.Frozen 提供 FrozenDictionary<TKey, TValue> 和FrozenSet<T> 集合。这些类型提供了一个不可变的表面区域,一旦创建,键或值就不可以进行任何更改。这反过来又使集合能够根据提供的数据更好地优化后续读取操作(例如 TryGetValue),从而使其能够在构造期有更多时间来优化所有未来的访问。这对于第一次使用时填充、且需在长期服务期间持续存在的集合特别有用,例如:
private static readonly FrozenDictionary<string, bool> s_configurationData =LoadConfigurationData().ToFrozenDictionary(optimizeForReads: true);
...
if (s_configurationData.TryGetValue(key, out bool setting) && setting)
{Process();
}
现有类型 ImmutableArray<T>.Builder 还获得了一种将其内容高效转换为 ImmutableArray<T> 的新方法。.NET 8 引入了DrainToImmutable(),它将当前内容作为不可变数组返回,并将构建器的集合重置为零长度数组,它会选择最有效的方法来执行此操作。基于元素的计数,我们可以使用此方法代替有条件地调用 ToImmutable()或 MoveToImmutable()。
新类型的另一个例子是 IndexOfAnyValues<T>,它能帮助开发人员预先投入一些时间以换取以后更快的执行速度。除了像 IndexOfAnyInRange 之类的新方法之外,还添加了接受 IndexOfAnyValues<T> 实例的新重载 IndexOfAny ,可以创建实例来表示要搜索的一组 T 值。此实例的创建处理派生任何必要的数据以优化后续搜索。例如,如果您经常搜索所有 ASCII 字母和数字以及一些标点符号字符,您之前可能会这样写:
private static readonly char[] s_chars = "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray();
...
int i = str.IndexOfAny(s_chars);
然而,这要求没有任何类型的向量化能够提高搜索效率,要么需要在每次调用 IndexOfAny 时花时间计算必要的状态以加速操作。现在,您可以这样写:
private static readonly IndexOfAnyValues<char> s_chars = IndexOfAnyValues.Create("-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz");
...
int i = str.AsSpan().IndexOfAny(s_chars);
预先计算所有该状态一次,以便在每次后续调用时都可以重用 IndexOfAny。
新类型 CompositeFormat 会自己反复这种模式。.NET 长期以来一直支持通过 API 进行字符串格式化,例如 string.Format 和 StringBuilder.AppendFormat,例如:
static string GetMessage(int min, int max) =>string.Format(CultureInfo.InvariantCulture, "Range from {0} to {1}", min, max);
C# 6 添加了对字符串插值的支持,然后 C# 10 结合 .NET 6 显著提高了这些操作的效率,使得相同的操作可以写成:
static string GetMessage(int min, int max) =>string.Create(CultureInfo.InvariantCulture, $"Range from {min} to {max}");
但是它是在编译时而不是在每次调用 string.Format 时执行可以预先计算的工作。 而这需要在编译时就能获取到格式字符串,以便可以在编译时对其进行解析……如果它直到运行时才获取到怎么办,例如,如果它是从资源文件或其他动态方式加载的?为此,.NET 8 添加了 CompositeFormat 类型。与 IndexOfAnyValues<T> 一样,它可以执行每次使用时需要执行的操作,然后将其取出执行一次。
private static readonly CompositeFormat s_rangeMessage = CompositeFormat.Parse(LoadRangeMessageResource());
...
static string GetMessage(int min, int max) =>string.Format(CultureInfo.InvariantCulture, s_rangeMessage, min, max);
这些新的重载还支持泛型参数,以避免装箱开销(boxing overheads)将所有内容都识别为 object。
.NET 8 预览版 1 还增加了对新的以性能为中心的哈希算法的支持,包括新的 XxHash3 和 XxHash128 类型,它们提供了快速 XXH3 和 XXH128 哈希算法的实现。
.NET SDK
dotnet publish 与 dotnet pack 默认生产 Release 资产
Publish(发布)和 Pack(打包)动词的目的是产生生产资产,这意味着它们应该生产Release 资产。在 .NET 8 中,他们将默认执行此操作。
此功能由 PublishRelease 和 PackRelease 布尔属性控制。默认为 true。
用 dotnet publish 演示该功能最简单:
/app# dotnet new console
/app# dotnet buildapp -> /app/bin/Debug/net8.0/app.dll
/app# dotnet publishapp -> /app/bin/Release/net8.0/app.dllapp -> /app/bin/Release/net8.0/publish/
/app# dotnet publish -p:PublishRelease=falseapp -> /app/bin/Debug/net8.0/app.dllapp -> /app/bin/Debug/net8.0/publish/
请注意,PublishRelease 并且 PackRelease 也存在于从 7.0.200 SDK 开始的 .NET 7 中。它们在 .NET 7 中是可选的,并且必须设置 true 才能执行相同的行为。
请参阅重大更改相关文档:
- dotnet publish
- dotnet pack
Linux 支持
从 dotnet/dotnet 构建您自己的 .NET
.NET 现在可以直接从 dotnet/dotnet 存储库在 Linux 上构建。它使用 dotnet/source-build 构建 .NET 运行时、工具和 SDK。例如,这与 Red Hat 和 Canonical 用于构建 .NET 的构建相同。随着时间的推移,我们将扩展其功能以支持 macOS 和 Windows。
请参阅构建说明以在您自己的计算机上构建 VMR。对于许多人来说,在容器中构建是最简单的方法,因为我们的 dotnet-buildtools/prereqs 容器镜像包含所有必需的依赖项。
我们称这个新存储库为 Virtual Mono Repository (VMR)。它具有真正的 monorepo 的优势,这多亏了开发者们每天在众多现有存储库中(更有效地)所做的定期更新。我们相信,VMR 和更小的“工作存储库”之间的分离是 .NET 项目的未来。我们希望在 VMR 中更容易构建横切功能,但是,我们目前还没有实现。
从源代码构建 .NET 并将其构建成一个完整产品是可行的,我们认为这个新方法就是我们向其迈出的重要一步。
在 .NET 8 之前,从源构建是可行的,但需要从与发布版本相对应的 dotnet/installer commit 提交创建 “source tarball” 。您不再需要进行这一操作。存储库将有与每个发布版本对应的标签,以及持续跟踪产品状态的 main 和 release/8.0-previewN 分支。
.NET 8 + Ubuntu Chiseled容器镜像
我们正在发布安装了 .NET 8 的 Ubuntu Chiseled 镜像. 相比常规容器,这种类型的镜像适用于希望使用有设备式计算优势的开发人员。我们预计,当 .NET 8上线时,Canonical 和 Microsoft 都将支持 Ubuntu chiseled 镜像。
我们计划从 .NET 8 开始,发布以 Ubuntu Chiseled 形式的 dotnet/monitor 镜像。值得一提的是,monitor 镜像是我们发布的生产应用镜像。
Chiseled images 有多种优势:
- 超小图像(减小尺寸和攻击面)
- 没有包管理器(避免整类攻击)
- 没有shell外壳(避免整类攻击)
- 没有 root(避免整类攻击)
您可以由此 aspnetapp sample 查看生产中的的 Chiseled 容器镜像。使用时,您只需要更改一行代码。
.NET 6 和 .NET 7 版本的 Chiseled 镜像现在已被发布到 nightly 存储库中。
Linux 支持和基线目标
我们正在更新支持 .NET 8 的 Linux 系统的最低基线。有三个变化需要注意。
- .NET 产品将针对 Ubuntu 16.04 版本进行构建,适用于所有体系结构。这对于定义 .NET 8 所需最低的 glibc 版本非常重要。例如,由于此项更改,.NET 8 将甚至无法在 Ubuntu 14.04 上启动。
- 对于 Red Hat Enterprise Linux(RHEL),我们将支持 RHEL 8+,启用 RHEL 7。
- 我们只会发布 RHEL 的支持声明,但是,我们希望也能支持其他 RHEL ecosystem distros 生态系统发行版。
重大变化主要就这些。我们仍将支持在 Arm32、Arm64 和 x64 架构上基础上使用 Linux。
请注意,这些更改仅适用于 Microsoft 内部版本。使用 source-build 构建的不同组织可能情况不同,通常为了一个构建生成构建版本仅适用于一个发行版版本,例如 Ubuntu 24.04。
下面演示了 Ubuntu 16.04 glibc 版本以及其用于其他发行版的模式。
$ docker run --rm ubuntu:16.04 ldd --version
ldd (Ubuntu GLIBC 2.23-0ubuntu11.3) 2.23
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
代码的生成
社区 PRs (非常感谢 JIT 论坛的 contributors!)
- @am11 更新了 CLRConfiguration 和 jithost 中的 env 变量 PR#77025。
- @En3Tho 将 (X & 1) != 0 优化为 (X & 1) 和 (X & 1) == 0 以及 ((NOT X) & 1) in PR#74806, 并修复了与 faulty LIR range 相关的漏 PR#77166。
- @MichalPetryka 实现了Type.IsEnum 和 Type.GetEnumUnderlyingType 在 PR#71685的内部函数, 并将MemoryMarshal.GetArrayDataReference 转换为 JIT 内部函数 PR#79760。
- @pedrobsaila 在 PR#62689 中做出了第一个 PR 贡献,发出无分支表单从 (x >= 0 && y >= 0) 到 (x | y) >= 0 ,从 (x != 0 && y != 0) 到 (x | y) != 0。
- @a74nh, @AndyJGraham and @swapnilGaikwad 对 Arm64 性能改进做出了贡献(请参阅 Arm64 部分)。
- @DeepakRajendrakumaran 为 AVX-512 做出了贡献(见AVX-512部分)。
- @SingleAccretion 为预览版本1进行了72个拉取请求 72 PR contributions 其中有:
1.PR#72719 优化的内存加载/在强制转换下存储
2.PR#77238 和 PR#76139 是与 SSA 相关的改进
3.PR#78246 通过删除 ADDR 节点简化 JIT IR
4.PR#77990 优化固定存储
云原生
- PR#79709 删除了非 GC 静态字段的帮助程序调用, PR#80969 优化了 GC 类型的静态字段。
- PR#80831 对单态案例实现将强制转换到接口进行非虚拟化。
Arm64
Arm64 性能改进工作正在按计划进行 Issue#77010。
- @AndyJGraham and @a74nh 实施了与 ldp 和 stp 相关的窥视孔优化 PR#77540
- @a74nh 在PR#73472, PR#77728, PR#78223, 和 PR#77888 中启用‘If Conversion’
- @swapnilGaikwad 在条件选择中使用零寄存器(csel) PR#78330
- @SwapnilGaikwad 在 PR#79550启用 mneg ,多选择中的一项 (Issue#68028)
- 通过比较PR#75864 和 PR#75999得出更快的矢量
- PR#75823 添加了对 Arm64 上的“移位寄存器”操作的支持
AVX-512
- .NET 8 将按计划支持 AVX-512 ISA 扩展 Issue#77034.
- PR#76642 实现了 API, 公开Issue#73262中Vector512<T> 类型
- 虚拟机中添加 AVX-512 状态已通过 @DeepakRajendrakumaran 的同意收到支持 PR#74113
- @DeepakRajendrakumaran 添加了对emitOutput 输出 路径的EVEX 编码支持PR#75934, PR#77419 和 PR#78044
- JitInterface 已由@DeepakRajendrakumaran 更新为Vector512 PR#81197
一般SIMD改进
- PR#77562 为在 Issue#76593 定义的 Vector64/128/256/512<T> 和 Vector<T>上新批准的 API 实施了额外的内部函数
- PR#79720 使用 HWIntrinsics 实现 Vector2/3/4 和 Vector<T>
- PR#77947 为 OrdinalIgnoreCase 矢量化 String.Equals
PGO
PGO 的基本改进正在按计划进行中 Issue#74873。
- 引入了新的 JIT 层,以仅检测热 Tier0 和 R2R 代码。这意味着您不再需要禁用 ReadyToRun 并牺牲启动时间来获得完全 PGO 级别的性能优势: PR#70941
- PR#80481 为所有场景启用了基于边缘的配置文件
- 构建预测列表已移至 JIT 的早期阶段:
PR#80625, PR#80856, PR#81288, PR#81246, PR#81196, PR#81000, 和 PR#80891。
循环优化
- PR#75140 在循环克隆中支持委托 GDV guards
- PR#80353 扩展循环展开优化
一般优化
@SingleAccretion 在PR#76263 Long中启用了32 位解锁字段注册上的多注册变量提升。
- PR#77103 实施了 Issue#8795中提出的新尾部合并优化
- PR#81055 确保 Span<T>.Length 和 ROSpan<T>.Length 被识别为“never negative”
- PR#79346 添加了一个早期的活跃度传递,允许 JIT 在传递结构参数时删除大量不必要的结构副本
- PR#77874 删除了一些涉及小整数类型的简单操作的不必要的零/符号扩展指令
- 字符串文字、typeof()、静态字段通过 PR#49576, PR#75573和 PR#76112
1.允许 JIT 在某些情况下省略 GC 写障碍 PR#76135
2.typeof(..) 在大多数情况下不再需要助手调用,例如:
Type GetMyType() => typeof(string); ; Method MyType():System.Type:this
3.4883EC28 sub rsp, 40
4.48B918083857FC7F0000 mov rcx, 0x7FFC57380818
5.E80DE8AB5F call CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE
6.90 nop
7.4883C428 add rsp, 40
8.48B8B800000364020000 mov rax, 0x264030000B8 ; ‘System.String’ C3 ret -; Total bytes of code: 25 +; Total bytes of code: 11
- 静态和静态只读字段的一批改
进 PR#77102, PR#77593, PR#77354, PR#77737, PR#78593, PR#78736 and PR#78783
- PR#81005 中显示的表达式就是一个很好的例子。JIT 现在能够在.NET 8 中折叠使用
JIT 吞吐量改进
- PR#80265 将 JitHashTable 迭代转换为基于范围的迭代for,将吞吐量提高了 0.22%
总之,.NET 8 预览版1的发布是 Microsoft 多元化工程师团队与高度参与的开源社区之间良好协作的证明。.NET 8 中的新功能和改进是社区成员辛勤努力和奉献的成果,我们非常感谢大家做出的贡献。
该社区重视包容性和多样性,能成为其中的一员,我们很自豪。我们致力于建立一个人人都可以访问的技术生态系统。我们相信,只要我们一起努力,就可以取得伟大的胜利,我们对 .NET 的未来充满期待。
点我阅读原博客,获取更多详细内容和相关链接~
相关文章:

.NET 8 预览版 1 发布!
.NET 8 是一个长期支持(LTS) 版本。这篇文章涵盖了推动增强功能优先级排序和选择开发的主要主题和目标。.NET 8 预览版和发布候选版本将每月交付一次。像往常一样,最终版本将在 11 月的某个时候在 .NET Conf 上发布。 .NET 版本包括产品、库、运行时和工具…...
WebGIS学习路线
7年经验的webgis码农在此文跟大家分享一些一路走来的所见所闻。希望能帮助刚刚跨入这个门槛的你。 入门之前我相信你已经搞清楚了以下几个问题: 1.什么是webgis? 2.webgis能够解决什么样的问题? 3.为什么你要学习webgis? 如果还没考虑清楚也没关系,可能你看完这篇文章…...
【独家】华为OD机试 - 停车场最大距离(C 语言解题)
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明本期…...
12.typedef的使用与结构体定义
欢迎访问个人网络日志🌹🌹知行空间🌹🌹 文章目录1.基础介绍2.typedef 的常用的几种情况3.使用typedef可能出现的问题参考资料1.基础介绍 typedef是C/C语言中保留的关键字,用来定义一种数据类型的别名。 typedef并没有…...

宝塔+docker+jenkins部署vue项目(保姆级教程)
1.使用宝塔安装docker 在软件商城安装Docker管理器 2.使用docker下载jenkins镜像 使用命令行 docker pull jenkins/jenkins:lts //lts表示支持版本较长3.创建并且挂载jenkins目录并赋值 jenkins_home为我创建的目录 可以修改任意目录 mkdir -p /jenkins_home cho…...

JVM面试总结
1.java内存模型JMM是java的内存模型,JMM-也叫Java Memory Model,这里反应翻译成存储更好,因为工作内存指的不是内存.而是CPU寄存器,主内存才是内存.屏蔽了各种硬件和操作系统的内存访问差异-把硬件的细节封装起来,实现让java程序在各平台下都能达到一致的内存访问效果,它定义了…...

C语言——文件操作
文章目录0. 思维导图1. 为什么使用文件2. 什么是文件2.1 程序文件2.2 数据文件2.3 文件名3. 文件的打开和关闭3.1 文件指针3.2 文件的打开和关闭4. 文件的顺序读写4.1 字符/字符串写入(出)4.2 格式化写入(出)4.3 二进制输入&#…...
使用aim7测试内核性能变化
aim7是一个功能强大的性能测试套件,可以用来测试内核的性能变化情况,尤其是在修改内核源码后,用来测试补丁对内核性能的影响情况。aim7测试结果中有一个重要的统计项:jobs/min,即每分钟完成的任务数量,可以…...

C++——内存管理
一,为什么要有内存管理因为在C/C中各个内置类型或者是自定义类型的大小都不一样,而如何让各个类型在内存中合理分布就非常有必要,由此我们就需要有内存管理。我们来看看下面这个程序中的各个变量都是如何分布的int globalVar 1; static int …...

AOP的另类用法 (权限校验自定义注解)
👳我亲爱的各位大佬们好😘😘😘 ♨️本篇文章记录的为 AOP的另类用法 (权限校验&&自定义注解) 相关内容,适合在学Java的小白,帮助新手快速上手,也适合复习中,面试中的大佬🙉🙉…...

[数据结构]:12-快速排序(顺序表指针实现形式)(C语言实现)
目录 前言 已完成内容 快速排序实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-PSeqListFunction.cpp 04-SortCommon.cpp 05-SortFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容,除其中使用到C引用外,全为C语言代…...

运算符——“Python”
各位CSDN的uu们你们好呀,好久没有更新Python文章了,今天,小雅兰的内容就是Python中的操作符啦,那么现在,就让我们进入Python的世界吧 注释 注释是什么 注释的语法 注释的规范 输入输出 和用户交互 通过控制台输出 通…...

2022 IoTDB Summit:华为王超《Apache IoTDB 在华为云的实践》
12 月 3 日、4日,2022 Apache IoTDB 物联网生态大会在线上圆满落幕。大会上发布 Apache IoTDB 的分布式 1.0 版本,并分享 Apache IoTDB 实现的数据管理技术与物联网场景实践案例,深入探讨了 Apache IoTDB 与物联网企业如何共建活跃生态&#…...

C 语言网络编程 — PF_NETLINK sockets
目录 文章目录目录PF_NETLINK socketsPF_NETLINK sockets Linux 提供了 4 种 User Process 和 Kernel 之间进行通信的 IPC(Inter-Process Communicate,进程间通信)方式: /procioctlsysfsPF_NETLINK sockets(Netlink …...

广州银行冲刺A股上市:不良贷款规模突破100亿元,不良率飙升
又一家城商行平移申报IPO。近日,广州银行股份有限公司(下称“广州银行”)递交招股书,准备在深圳证券交易所主板上市。本次冲刺上市,广州银行计划募资约94.79亿元,国泰君安证券为其保荐机构。 截至目前&…...

【C++】bsearch函数的使用及二分法查找介绍
写程序的时候,肯定避免不了需要从集合中找到符合条件的元素,一般情况下,最简单也最常用的就是循环遍历元素,这种方法虽然写的简单,但是小数据量还行,但是数据过大的话,这样效率就低了。循环的时…...

分布式系统中的补偿机制设计问题
我们知道,应用系统在分布式的情况下,在通信时会有着一个显著的问题,即一个业务流程往往需要组合一组服务,且单单一次通信可能会经过 DNS 服务,网卡、交换机、路由器、负载均衡等设备,而这些服务于设备都不一…...

类成员的方法
初识对象 生活中或是程序中,我们都可以使用设计表格、生产表格、填写表格的形式组织数据进行对比,在程序中: 设计表格,称之为:设计类(class) 打印表格,称之为:创建对象 …...
华为OD机试真题Python实现【端口合并】真题+解题思路+代码(20222023)
端口合并 题目 有M(1<=M<=10)个端口组, 每个端口组是长度为N(1<=N<=100)的整数数组, 如果端口组间存在 2 个及以上不同端口相同, 则认为这 2 个端口组互相关联,可以合并 第一行输入端口组个数 M,再输入 M 行,每行逗号分隔,代表端口组。 输出合并后的端口组…...

自考本科计算机网络原理(04741)历年大题真题【18年10月-22年10月】
文章目录一、简答题(历年真题)18年10月-22年10月历年简答题出题情况分析2018年10月2019年4月2019年10月2020年8月2020年10月2021年4月2021年10月2022年4月2022年10月二、综合题(历年真题)2018年10月2019年4月2019年10月2020年8月2…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...

ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...