news 2026/5/1 9:07:54

.NET10 New feature 新增功能介绍-JIT编译器改进

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
.NET10 New feature 新增功能介绍-JIT编译器改进

首先.NET10是一个LTS版本,微软官方支持3年,所以作为最新的主力版本,可以尽快升级使用。

今天我们详细介绍一下.NET 10的一些新功能-JIT编译器改进

.NET 10 的 JIT 改进不是让慢代码变快,而是让“设计良好的代码不再被性能惩罚”。

对业务代码是否有“侵入性”?几乎没有

  • 不需要改写代码

  • 不需要 unsafe

  • 不需要特殊编译选项

你写的是“好代码”,JIT 会越来越聪明地帮你榨干性能。

.NET 10 中的 JIT 编译器包括通过更好的代码生成和优化策略提高性能的重要增强功能。改进结构参数的代码生成

.NET 的 JIT 编译器能够进行称为物理提升的优化,其中结构的成员放置在寄存器而不是堆栈中,从而消除了内存访问。 将结构传递给方法时,此优化特别有用,调用约定要求在寄存器中传递结构成员。

.NET 10 改进了 JIT 编译器的内部表示形式,以处理共享寄存器的值。 以前,当需要将结构成员打包到单个寄存器中时,JIT 将首先将值存储在内存中,然后将其加载到寄存器中。 现在,JIT 编译器可以将结构参数的优化成员直接存储到共享寄存器中,从而消除不必要的内存操作。

struct Point { public long X; public long Y; public Point(long x, long y) { X = x; Y = y; } } [MethodImpl(MethodImplOptions.NoInlining)] private static void Consume(Point p) { Console.WriteLine(p.X + p.Y); } private static void Main() { Point p = new Point(10, 20); Consume(p); }

在 x64 CPU架构上,/* by 01130.hk - online tools website : 01130.hk/zh/formatxml.html */ Point的成员会分配到单独的寄存器,并传递给/* by 01130.hk - online tools website : 01130.hk/zh/formatxml.html */ Consume。由于本地p的物理提升已启动,因此最初不会在堆栈上分配任何内容。

Program:Main() (FullOpts):
mov edi, 10
mov esi, 20
tail.jmp [Program:Consume(Program+Point)]

现在,假设成员Point的类型已更改为int而不是long。 由于 aint为四个字节宽,寄存器在 x64 上宽 8 个字节,因此调用约定要求在一个寄存器中传递成员Point

以前,JIT 编译器首先将值存储到内存中,然后将八字节区块加载到寄存器中。

在.NET 10中,JIT 编译器现在可以直接将结构参数的提升成员放入共享寄存器中:

Program:Main() (FullOpts):
mov rdi, 0x140000000A
tail.jmp [Program:Consume(Program+Point)]

这样就不需要中间内存存储,从而生成更高效的程序集代码。

改进了循环转化

JIT 编译器可以提升循环的条件while,并将循环体转换为do-while循环,从而生成最终形状:

if (loopCondition) { do { // loop body } while (loopCondition); }

此转换称为循环反转。 通过将条件移动到循环底部,JIT 无需将分支到循环顶部来测试条件,从而改进代码布局。 许多优化(如循环克隆、循环展开和感应变量优化)也依赖于循环反转来生成此形状来帮助分析。

.NET 10 通过从词法分析实现切换到基于图形的循环识别实现来增强循环反转。

此更改会考虑所有自然循环(即只有单个入口点的循环)并忽略以前被考虑的误报,从而提高了精度。 这使得包含forwhile语句的 .NET 程序具有了更高的优化潜力。

数组接口方法反虚拟化

.NET 10 的重点 领域 之一是减少常用语言功能的抽象开销。 为了追求此目标,JIT 去虚拟化方法调用的能力已经扩展为涵盖数组接口方法。

请考虑遍历一个数组的典型方法:

static int Sum(int[] array) { int sum = 0; for (int i = 0; i < array.Length; i++) { sum += array[i]; } return sum; }

此代码形式易于 JIT 优化,主要是因为不存在虚拟调用。 相反,JIT 可以专注于删除对数组访问的边界检查,并应用 .NET 9 中添加的循环优化。 以下示例添加一些虚拟调用:

static int Sum(int[] array) { int sum = 0; IEnumerable<int> temp = array; foreach (var num in temp) { sum += num; } return sum; }

基础集合的类型是明确的,JIT 应该能够将此代码片段转换为第一个代码片段。 但是,数组接口的实现方式与“普通”接口不同,因此 JIT 不知道如何对它们进行反虚拟化。 这意味着循环中的foreach枚举器调用仍然是虚拟的,从而阻止了多个优化,例如内联和堆栈分配。

从 .NET 10 开始,JIT 可以取消虚拟化和内联数组接口方法。 这是实现两者性能相等的诸多步骤中的第一步,如.NET 10 去抽象计划中所述。

内联改进

.NET 10 中进行了各种内联改进。

JIT 现在可以内联因以前的内联而适合实现非虚拟化的方法。 这种改进使 JIT 可以发现更多的优化机会,例如进一步内联和去虚拟化。

某些具有异常处理语义的方法(尤其是具有try-finally块的方法)也可以内联。

为了更好地利用 JIT 的堆栈分配某些数组的能力,内联器的启发式算法已进行调整,以提高可能返回小型固定大小数组的候选项的收益。

返回类型

在内联过程中,JIT 编译器现在会更新临时变量的类型,这些变量用于存储返回值。 如果被调用方中的所有返回站点都生成相同的类型,则使用此精确的类型信息来取消后续调用的虚拟化。 此增强功能补充了后期非虚拟化和数组枚举去抽象的改进。

配置文件数据

.NET 10 改进了 JIT 的内联策略,以更好地利用配置文件数据。 在众多启发式算法中,JIT 内联器不会对超过一定大小的方法进行内联,以避免使调用方法变得臃肿。 当调用方拥有表明某个内联候选函数被频繁执行的配置文件数据时,内联器会增加对该候选函数的大小容忍度。

假设 JIT 将没有配置文件数据的被调用方Callee内联到具有配置文件数据的调用方Caller中。 这种不一致可能发生在被调用方过小而不值得进行检测,或者被调用方被内联调用过于频繁,从而导致调用次数不足。 如果Callee拥有自己的内联候选项,JIT 此前并未将其纳入考虑范围,因为Callee缺乏性能分析数据。 现在,JIT 将识别到Caller拥有配置文件数据,并因此放宽其大小限制(但为了弥补精度损失,这种放宽程度不及Callee拥有配置文件数据时)。

同样,当 JIT 决定某个调用点不适合进行内联优化时,它会用NoInlining标记该方法,以避免未来再次尝试对该方法进行内联优化。 但是,许多内联启发法对配置文件数据很敏感。 例如,在缺少配置文件数据的情况下,JIT 可能会认为某个方法太大而不值得进行内联。 但是,当调用方足够热时,JIT 可能愿意放宽其大小限制并内联调用。 在 .NET 10 中,JIT 不再用NoInlining标记那些无利可图的内联函数,以避免配置文件数据导致调用点的性能恶化。

堆栈分配

堆栈分配可减少 GC 必须跟踪的对象数,并且还会解锁其他优化。 例如,在对象被堆栈分配后,JIT 可以考虑将其完全替换为其标量值。 因此,堆栈分配是减少引用类型的抽象惩罚的关键。 .NET 10 为值类型和引用类型的小型数组添加堆栈分配。 它还包括对本地结构字段和委托的转义分析。 (无法转义的对象可以在堆栈上分配。)

周国庆

2025/12/21

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 16:02:07

软件缺陷模式解析与应对策略

在软件开发生命周期中&#xff0c;缺陷是不可避免的挑战。对软件测试从业者而言&#xff0c;理解常见缺陷模式不仅有助于高效定位问题&#xff0c;还能推动缺陷预防和过程改进。本文基于行业实践&#xff0c;系统梳理了常见软件缺陷模式&#xff0c;分析其根本原因、表现形式及…

作者头像 李华
网站建设 2026/5/1 6:14:15

【Open-AutoGLM安全认证全攻略】:掌握企业级访问控制的5大核心机制

第一章&#xff1a;Open-AutoGLM安全认证概述 Open-AutoGLM 是一款面向自动化代码生成与大模型集成的开源框架&#xff0c;其核心组件支持多语言代码生成、智能补全与上下文推理。为确保系统在复杂部署环境下的安全性与可信性&#xff0c;Open-AutoGLM 引入了多层次的安全认证机…

作者头像 李华
网站建设 2026/4/30 16:38:35

测试之禅:在确定性与不确定性之间寻找平衡

在软件测试的世界里&#xff0c;我们始终行走在确定性与不确定性的钢丝上。确定性给予我们可靠的基准——明确的需求、可重复的测试用例、稳定的测试环境&#xff1b;而不确定性则无处不在——突发的生产缺陷、难以复现的偶发bug、不断变化的用户行为模式。优秀的测试工程师不是…

作者头像 李华
网站建设 2026/5/1 4:48:14

Open-AutoGLM压力测试全流程拆解(含GPU利用率翻倍的3个隐藏配置)

第一章&#xff1a;Open-AutoGLM 性能基准测试工具Open-AutoGLM 是一个专为评估大型语言模型在自动化任务中表现而设计的开源基准测试框架。它聚焦于衡量模型在代码生成、指令理解、上下文推理和多轮交互等关键能力上的性能&#xff0c;适用于科研与工业场景下的模型对比与优化…

作者头像 李华
网站建设 2026/5/1 4:48:08

Excalidraw使用技巧大全:高效绘制技术草图的秘密

Excalidraw使用技巧大全&#xff1a;高效绘制技术草图的秘密 在一场远程架构评审会议中&#xff0c;团队成员正围绕系统拓扑展开激烈讨论。有人提出“微服务间通信链路是否该引入服务网格”&#xff0c;但仅靠语言描述难以厘清边界。这时&#xff0c;一位工程师迅速打开浏览器&…

作者头像 李华
网站建设 2026/5/1 4:48:17

智慧校园建设成效如何科学评估?构建合理评价体系是关键

✅作者简介&#xff1a;合肥自友科技 &#x1f4cc;核心产品&#xff1a;智慧校园平台(包括教工管理、学工管理、教务管理、考务管理、后勤管理、德育管理、资产管理、公寓管理、实习管理、就业管理、离校管理、科研平台、档案管理、学生平台等26个子平台) 。公司所有人员均有多…

作者头像 李华