c# - C# JIT 编译器是否优化空值检查?

标签 c# .net optimization jit null-check

网上有很多文章列出了C# JIT在执行一段代码之前所做的优化。例如this post在 MSDN 上讨论:

Constant folding, Constant and copy propagation, Common subexpression elimination, Code motion of loop invariants, Dead store and dead code elimination, Register allocation, Method inlining, Loop unrolling (small loops with small bodies).

我的问题是:JIT 编译器是否也处理无用的空值检查?我找不到任何来源来处理这个问题。

在我读到的同一篇文章中:

since the C# language specification ensures that any call on a null object reference throws a NullReferenceException, every call site must ensure the instance is not null. This is done by dereferencing the instance reference; if it is null it will generate a fault that is turned into this exception.

所以,假设我写了一段这样的代码:

if (person != null)
{
    Console.WriteLine(person.Name);
}

person.Name 再次调用显然无用的第二个 null 检查,编译器可以将其删除。还是不行?

我读到在 Java 中这已经完成了(许多 hereherehere 之间的一些来源)。

如果 C# 也这样做,您是否知道一些讨论该问题的来源或文档?

如果 C# 不这样做,您知道为什么吗?在 Java JIT 不会遇到的 .NET 环境中实现这样的功能是否存在内在困难?

最佳答案

Null 检查编译器完成的优化(Roslyn,而非 Jitter)in several cases ,当它完全保存时。

例如,当您使用 ?(Elvis 运算符)时。

IL_0006: stloc.0              // Pop a value from stack into local variable 0
IL_0007: ldloc.0              // Load local variable 0 onto stack
IL_0008: brtrue.s IL_000c     // Branch to target if value is non-zero (true), short form
IL_000a: br.s IL_0013         // Branch to target, short form
IL_000c: ldloc.0              // Load local variable 0 onto stack
IL_000d: call instance void Foo::Bar() // Call method indicated on the stack with arguments

另一个例子是这样的代码:

new Bar().Foo();

编译器为这个 call 指令而不是 callvirt 生成(这意味着,没有对 this 进行空检查)

在其他情况下,您无法确定 this 不会为 null。

不管怎样,null 检查真的非常快。

关于c# - C# JIT 编译器是否优化空值检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41004069/

相关文章:

c# - 是否可以将 Type.GetType 与动态加载的程序集一起使用?

c# - 如何保存具有透明背景的 gif?

java代码优化,会不会优化这个

c# - WPF路径碰撞检测?

c# - 从 app.config 注入(inject)连接字符串与从 BaseDataProvider 类读取它

c# - Kestrel 配置使用特定端口 + url

c# - C# 或 JIT 编译器是否足够智能以处理此问题?

c# - Reflection.Emit:在 getter/setter 中调用函数的属性

c# - 分布式事务 : . NET Framework 与 .NET Core

sql userid + name + profile 优化问题