Ert*_*maa 21 .net c# optimization jit decimal
当我发现这个时,我正在阅读.NET源代码:
// Constructs a Decimal from an integer value.
//
public Decimal(int value) {
// JIT today can't inline methods that contains "starg" opcode.
// For more details, see DevDiv Bugs 81184: x86 JIT CQ:
// Removing the inline striction of "starg".
int value_copy = value;
if (value_copy >= 0) {
flags = 0;
}
else {
flags = SignMask;
value_copy = -value_copy;
}
lo = value_copy;
mid = 0;
hi = 0;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,Decimal结构的构造函数将方法参数复制到局部变量,而不是直接使用它.我想知道评论的含义以及它与性能和优化的关系?
我的猜测是,一旦你想修改现有的参数,方法就不能再内联了?
http://referencesource.microsoft.com/#mscorlib/system/decimal.cs#f9a4da9d6e110054#references
sta*_*ica 16
我的猜测是,一旦你
想修改现有的参数,方法就不能再内联了?
简短的回答:你的猜测是正确的(如果今天的源代码评论仍然是真的).
Run Code Online (Sandbox Code Playgroud)// JIT today can't inline methods that contains "starg" opcode.
"JIT"是.NET运行时的一部分,它将中间语言(IL)(即.NET"字节码")转换为计算机的汇编语言.只有这样,您的计算机才能执行代码.JIT逐个方法地执行这种转换方法,并且仅在实际需要时:每当首次调用方法时,首先将其编译为实际汇编语言,"实时"(JIT).
C#编译器不会立即为您的计算机体系结构生成汇编语言; 相反,它生成中间语言,这是一种抽象堆栈机器(在ECMA 334国际标准中定义)的某种汇编语言.
例如,对参数的赋值(在您的示例中value:)将由C#编译器转换为称为starg("store to argument")的IL指令.
注释基本上说如果方法包含这样的赋值(value = …),那么JIT目前无法"内联"它."内联方法"意味着JIT不是生成对方法的调用指令(即将命令分支到不同的代码位置),而是将方法的整个主体插入到调用它的位置.这通常是为了优化执行速度,因为不需要分支/跳转,另外我假设也不必设置新的堆栈帧.
通过赋值给局部变量(value_copy = …),可以规避JIT的这种限制,因为对局部变量的赋值会导致生成不同的IL指令:( stloc"存储到局部变量").
也可以看看: