为什么 .NET JIT 编译器决定不内联或优化对没有副作用的空静态方法的调用?

2024-01-10

我认为我观察到 .NET JIT 编译器没有内联或优化对没有副作用的空静态方法的调用,考虑到一些定制的在线资源,这有点令人惊讶。

我的环境是 x64、Windows 8.1、.NET Framework 4.5 上的 Visual Studio 2013。

鉴于这个简单的测试程序(https://ideone.com/2BRCpC https://ideone.com/2BRCpC)

class Program
{
    static void EmptyBody()
    {
    }

    static void Main()
    {
        EmptyBody();
    }
}

对上述程序进行优化的发布版本会生成以下 MSIL:Main and EmptyBody:

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       6 (0x6)
  .maxstack  8
  IL_0000:  call       void Program::EmptyBody()
  IL_0005:  ret
} // end of method Program::Main

.method private hidebysig static void  EmptyBody() cil managed
{
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method Program::EmptyBody

MSIL 包含来自以下位置的调用并不奇怪Main to EmptyBody,因为 C# 编译器预计不会内联或优化此类调用。然而,我认为 JIT 编译器会内联或优化掉该调用。但这似乎并没有发生。

如果我运行上面的程序并进入调试器Main,生成的程序集是这样的:

00572621  mov         ebp,esp  
00572623  cmp         dword ptr ds:[4320B84h],0  
0057262A  je          00572631  
0057262C  call        73E6AF20  
00572631  call        dword ptr ds:[4321578h]  

指令指针立即设置到最后一行 00572631,这是对EmptyBody。步入EmptyBody,发现生成的程序集是

00BD2651  mov         ebp,esp  
00BD2653  cmp         dword ptr ds:[4B00B84h],0  
00BD265A  je          00BD2661  
00BD265C  call        73E6AF20  
00BD2661  nop  
00BD2662  pop         ebp  
00BD2663  ret

指令指针立即设置为nop00BD2661 处的行,它没有做任何事情,我无法猜测为什么它首先生成。

鉴于上面的两个程序集片段共享相同的 4 指令标头,我假设这只是设置堆栈等的常规方法入口样板。不过,我很想知道这些重复的指令会做什么:

00BD2653  cmp         dword ptr ds:[4B00B84h],0  
00BD265A  je          00BD2661  
00BD265C  call        73E6AF20  

无论如何,主要问题是:为什么 JIT 编译器会生成调用空体静态方法的程序集EmptyBody?


经过进一步挖掘,事实证明我可以自己回答这个问题。正如所解释的http://blogs.msdn.com/b/vancem/archive/2006/02/20/535807.aspx http://blogs.msdn.com/b/vancem/archive/2006/02/20/535807.aspx,在调试器下观察优化发布版本的反汇编默认情况下会影响 JIT 编译器。

取消选中这些

  • “抑制模块加载的 JIT 优化”
  • “仅启用我的代码”

在 VS > Tools > Debugging > General 下,将显示“真实的”JIT 编译结果,用于调用EmptyBody in my Main上面是这样的:

004C2620  ret

这意味着调用EmptyBody被完全移除,这是预期的,世界仍然是一个快乐且有点可预测的居住地:)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 .NET JIT 编译器决定不内联或优化对没有副作用的空静态方法的调用? 的相关文章

随机推荐

  • CSS :nth-of-type() 和 :not() 选择器?

    我并排浮动了 25 宽的文章 我正在添加一个clear both每四个元素之后 但是我需要在元素之间插入图形分节符 它必须在 ul 为了有效 我将 分节符 下面示例中的第一个 li 项 包装成 li 以及 ul li class year
  • ValueError:预期的 2D 或 3D 输入(获得 1D 输入)PyTorch

    class VAE torch nn Module def init self input size hidden sizes batch size super VAE self init self input size input siz
  • cspack 行为与 msbuild 不同

    使用 Visual Studio 2012 Azure SDK 2 1 我试图找出创建 csx 文件夹以在 azure 模拟器中运行的最佳方法 我的理解是 在打包 Azure 项目之前 不会创建 csx 文件夹 我可以从 Visual St
  • 无法在 iOS 上使用自定义 @protocol

    注意 以下是使用启用了自动引用计数 ARC 的 iOS 我认为 ARC 可能与它不起作用有很大关系 因为这是根据我通过谷歌找到的示例设置的 我正在尝试创建一个协议来通知委托用户从 UITableView 选择的文件名 文件列表视图控制器 h
  • 离子搜索栏搜索不适用于 cypress {enter}

    我有一个 Ionic 6 应用程序 我正在使用 cypress 9 3 1 对其进行测试 在我的应用程序中 我使用像这样的离子搜索栏
  • 插入...值(SELECT ... FROM ...)

    我在尝试着INSERT INTO使用另一个表的输入的表 尽管这对于许多数据库引擎来说是完全可行的 但我似乎总是很难记住正确的语法SQL当天的发动机 MySQL http en wikipedia org wiki MySQL Oracle
  • WPF DPI 问题

    我开发了一个应用程序 在我的计算机上看起来很棒 但当我将其安装到具有不同分辨率和 DPI 设置的其他计算机上时 它看起来很糟糕 控件相互重叠 这真是太痛苦了 有人对如何避免这种情况有什么建议吗 Windows 无法知道屏幕的本机 DPI 每
  • Python3 - 无法读取 docx、odt 文件 - UnicodeDecodeError:“utf-8”编解码器无法解码位置 10 中的字节 0xea:无效的连续字节

    我正在尝试将大 docx 文件拆分为小文件 为此 当读取文件时python3 6使用以下代码 with open h docx r as f a f read 它抛出这个错误 Traceback most recent call last
  • Linux 中的沙箱

    我想创建一个 Web 应用程序 允许用户上传一些 C 代码 并查看其执行结果 代码将在服务器上编译 用户不受信任 这显然会带来巨大的安全隐患 所以我需要为应用程序创建某种沙箱 在最基本的层面上 我想将对文件系统的访问限制为某些指定的目录 我
  • Spring JPA 中的 @Entity 是什么?

    具体来说 我指的是javax persistence Entity 根据我将鼠标悬停在上面时显示的文档 在 VS Code 中它指出 指定该类是一个实体 该注解适用于 实体类 对于 Spring JPA 来说 类是实体意味着什么 Entit
  • GetComInterfaceForObject 是否固定对象?

    使用 GetComInterfaceForObject 并将返回的 IntPtr 传递给非托管代码是否会阻止托管对象在内存中移动 或者 clr 是否以某种方式维护该 ptr 请注意 非托管代码将在程序的生命周期内使用它 并且我需要确保托管对
  • 在单个测试类中测试接口的多个实现

    我需要通过班级级别的测试数据但是Theory and InlineData属性只能用在方法上 public class ContainerTests TestFixture private IContainer container publ
  • 在 GPU 上预加载整个数据集以训练 Keras 模型

    我有一个特定的情况 其中网络相对较小 为了收敛和泛化问题 我应该保持较小的批量大小 例如 256 这导致每个时期要处理数百个批量 不幸的是 在这种情况下 批量 加载和损失计算成为瓶颈 如timeline工具告诉我 在 TensorFlow
  • spring可以支持多应用共享成员资格吗?

    spring 框架是否支持共享公共用户群的多个应用程序 例如2 个独立的 Web 应用程序以某种方式连接到单个数据库以获取用户相关信息 用户名 密码 甚至角色 这个想法是这样的 类似于ASP NET 会员资格 http msdn micro
  • 图像隐写术抵御各种攻击的最佳实践是什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我对此真的很好奇 因为现在每个频道都可以以某种方式修改或压缩图像 这可以被视为对隐写术的攻击 我们可以将隐写术分为两种基本类型 第一种在图像的空
  • ClassNotFound launchig 地图活动在 Android 库中声明

    当尝试启动从 MapActivity 派生并在 Android 库项目中声明的活动 TestLocationActivity 时 我收到此异常 09 08 09 29 45 357 ERROR AndroidRuntime 7502 jav
  • 是否可以更改Matlab绘图功能中的标记? [复制]

    这个问题在这里已经有答案了 我正在尝试使用 matlab 绘图函数来创建绘图 然而 可用的标记是有限的 例如 plot x y o 将用圆形标记绘制 但是 如果我想要带有箭头符号或字母的标记 这是不可能的 有谁知道有什么方法可以做到这一点
  • Excel VBA 调试:循环不搜索整个范围

    我编写了一个基本宏来搜索范围 在一张纸中 然后根据保存选择值的第三张纸复制所选单元格 到另一张纸 我已经使用了 i x to y 的循环 但看起来宏正在跳过一些行 即 如果第 1 行到第 4 行有 4 个要复制的有效值 则宏仅复制第 2 行
  • 如何拥有连续的 Firebase 云函数来获取连续的数据流?

    我需要使用 Twitter Stream API 将推文数据流式传输到我的 firebase 云函数 如下所示 client stream statuses filter params stream gt stream on data tw
  • 为什么 .NET JIT 编译器决定不内联或优化对没有副作用的空静态方法的调用?

    我认为我观察到 NET JIT 编译器没有内联或优化对没有副作用的空静态方法的调用 考虑到一些定制的在线资源 这有点令人惊讶 我的环境是 x64 Windows 8 1 NET Framework 4 5 上的 Visual Studio