gpt4 book ai didi

c# - 为什么 C# 编译器不优化掉重复的局部变量默认值初始化?

转载 作者:太空狗 更新时间:2023-10-29 23:46:27 27 4
gpt4 key购买 nike

背景

我知道 Compiler 会“省略为字段生成 int foo = 0; 之类的代码,因为内存分配器会将字段初始化为默认值。” Reference

        class Foo
{
public int a = 1;
public int b = 0;
}
Foo..ctor:
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: stfld UserQuery+Foo.a // There is no b.
IL_0007: ldarg.0
IL_0008: call System.Object..ctor
IL_000D: ret

我还知道“编译器会自动在每个使用局部变量的方法上添加 .locals init,表明 JIT 必须在开始执行方法之前注入(inject)初始化所有局部变量的代码。” Reference

问题

为什么编译器不为 int foo = 0; 之类的局部变量忽略生成 IL,因为 .locals init 已经涵盖了这些? (为了与字段保持一致?)

(我理解 C# 规范要求明确分配局部变量,我同意这一点。)

(我引用的链接说明了为什么需要 .locals init 的原因,以及为什么 C# 规范要求初始化局部变量。但它没有说明为什么要使用额外的 IL 指令来初始化默认值必须存在。因为验证过程已由 .locals init 确保)

void Main()
{
int a = 0;
int b = 1;
int c = 0;
int d = a + b + c;
d++;
}

.maxstack 2
.locals init (int a, int b, int c, int d)

IL_0000: ldc.i4.0
IL_0001: stloc.0 // a (Can be optimized away)
IL_0002: ldc.i4.1
IL_0003: stloc.1 // b
IL_0004: ldc.i4.0
IL_0005: stloc.2 // c (Can be optimized away)
IL_0006: ldloc.0 // a
IL_0007: ldloc.1 // b
IL_0008: add
IL_0009: ldloc.2 // c
IL_000A: add
IL_000B: stloc.3 // d
IL_000C: ldloc.3 // d
IL_000D: ldc.i4.1
IL_000E: add
IL_000F: stloc.3 // d

最佳答案

Why doesn't compiler omit generating IL for things like int foo = 0; for local variables since .locals init already cover that?

为什么要这样?我还没有实际验证这一点,但如果您删除不必要的初始化,JIT 编译器会生成不同的 native 代码,我会感到惊讶。

这意味着将此优化添加到 C# 编译器的唯一好处是使 JIT 编译稍微快一点(因为它必须处理更少量的 IL 代码)。 C# 编译器的作者似乎认为为了如此微小的好处而进行这种优化是不值得的。

关于c# - 为什么 C# 编译器不优化掉重复的局部变量默认值初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17277199/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com