当我发现这个时,我正在通读 .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;
}
如您所见,Decimal 结构的构造函数将方法参数复制到局部变量,而不是直接使用它。我想知道评论的含义以及它与性能和优化有何关系?
我的猜测是一旦你想修改现有的参数,方法就不能再内联了?
http://referencesource.microsoft.com/#mscorlib/system/decimal.cs#f9a4da9d6e110054#references
最佳答案
My guess is that once you
want tomodify the existing argument, method can be no longer inlined?
简答:您的猜测是正确的(如果该源代码注释今天仍然正确的话)。
// JIT today can't inline methods that contains "starg" opcode.
“JIT” 是 .NET 运行时翻译 intermediate language (IL) (i.e. .NET "bytecode") 的那部分到您计算机的汇编语言。只有这样,您的计算机才能执行代码。 JIT 逐个执行此转换方法,并且仅在实际需要时执行:每当首次调用方法时,它首先被编译为实际的汇编语言,即“即时”(JIT)。
C# 编译器不会立即为您的计算机体系结构生成汇编语言;相反,它生成 intermediate language ,这是一种用于抽象堆栈机器的汇编语言(在 ECMA 334 international standard 中定义)。
例如,对参数的赋值(在您的示例中:value
)会被 C# 编译器翻译成名为 starg
的 IL 指令(“存储到参数”)。
评论基本上是说,如果方法包含这样的赋值(value = …
),那么 JIT 当前将无法“内联”它。 <强> "Inlining a method" 意味着 JIT 不是生成方法的调用指令(即分支命令到不同的代码位置),而是将方法的整个主体插入到调用它的地方。这通常是为了优化执行速度,因为不需要分支/跳转,另外我假设也不需要设置新的堆栈框架。
通过分配给局部变量(value_copy = …
),JIT 的这个限制被规避了,因为分配给局部变量会导致生成不同的 IL 指令:STLoc
(“存储到局部变量”)。
另请参阅:
关于c# - .NET 局部变量优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26369163/