.NET 7的性能改进有哪些具体细节?

摘要:原文 | Stephen Toub 翻译 | 郑子铭 循环提升和克隆 (Loop Hoisting and Cloning) 我们之前看到PGO是如何与循环提升和克隆互动的,这些优化也有其他改进。 从历史上看,JIT对提升的支持仅限于将一个
原文 | Stephen Toub 翻译 | 郑子铭 循环提升和克隆 (Loop Hoisting and Cloning) 我们之前看到PGO是如何与循环提升和克隆互动的,这些优化也有其他改进。 从历史上看,JIT对提升的支持仅限于将一个不变量提升到一个层级。 考虑一下这个例子: [Benchmark] public void Compute() { for (int thousands = 0; thousands < 10; thousands++) { for (int hundreds = 0; hundreds < 10; hundreds++) { for (int tens = 0; tens < 10; tens++) { for (int ones = 0; ones < 10; ones++) { int n = ComputeNumber(thousands, hundreds, tens, ones); Process(n); } } } } } static int ComputeNumber(int thousands, int hundreds, int tens, int ones) => (thousands * 1000) + (hundreds * 100) + (tens * 10) + ones; [MethodImpl(MethodImplOptions.NoInlining)] static void Process(int n) { } 乍一看,你可能会说:"有什么可提升的,n的计算需要所有的循环输入,而所有的计算都在ComputeNumber中。" 但从编译器的角度来看,ComputeNumber函数是可内联的,因此在逻辑上可以成为其调用者的一部分,n的计算实际上被分成了多块,每块都可以被提升到不同的层级,例如,十的计算可以提升出一层,百的提升出两层,千的提升出三层。下面是[DisassemblyDiagnoser]对.NET 6的输出。
阅读全文