1.前言
这里展示一个比较实用的小方法。如果你觉得程序里某个方法非常的慢,但是又不知道怎么去优化。那么可以交给JIT去进行自动化的优化。只需要开启当前程序集的一个标志即可。本篇看下。
2.用法
看一个简单例子:
using System;
using System.Diagnostics;
namespace ConsoleApp1{
public class Test{
internal class Program{
static void ABC(){
}
static void Main(string[] args){
ABC();
Console.ReadLine();
ABC();
ABC();
ABC();
}
}
}
}
ABC方法被调用了四次,按照分层编译的原理
TieredCompilation_CallCountThreshold环境变量的默认值是2,因为中间运行了
Console.ReadLine();
所以tieredCompilation_CallCountingDelayMs也是超过1ms的时间的。
这两个条件满足,就会加入到分层编译(.NET8例外,下面会提到),但是因为ABC属于普通的程序集方法,也就是默认的程序集标志如下:
DebuggingModes.DisableOptimizations
这个标志对于普通程序集方法分层编译是无效的 。所以在.NET7里面ABC方法基本上不会被分层编译。
这时候你就可以在using下面添加如下程序集特性即可让JIT帮你优化你当前程序集里面的所有方法。
[assembly: Debuggable( DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
整体的代码如下:
using System;
using System.Diagnostics;
[assembly: Debuggable( DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
namespace ConsoleApp1{
public class Test{
internal class Program{
static void ABC(){
}
static void Main(string[] args){
ABC();
Console.ReadLine();
ABC();
ABC();
ABC();
}
}
}
}
注意添加的assembly: Debuggable的特性标志.NET8里面无论有没有超过
tieredCompilation_CallCountingDelayMs的值,只要设置了如下标志,都会加入到分层编译。:
DebuggingModes.IgnoreSymbolStoreSequencePoints
它是告诉Roslyn前端编译器,需要设置托管DLL里的元数据的Blob Index相对应的值为0x00002.
DebuggingModes的值如下:
public enum DebuggingModes
{
None = 0,
Default = 1,
IgnoreSymbolStoreSequencePoints = 2,
EnableEditAndContinue = 4,
DisableOptimizations = 256
}
当JIT检测到托管DLL元数据#~表的某个CustomAttribute项Blob Index为0x00002的时候,JIT便会对整个托管DLL里面的程序集方法进行分层编译
DebuggingModes.IgnoreSymbolStoreSequencePoints
需要注意的是,这个特性是全局性的。它是告诉JIT优化整个程序集里面的方法,而不是单独某一个方法。