1

可能重复:
C# 64 位发布代码的反汇编视图比 32 位调试代码长 75%?

我有一个非常简单的 C# 控制台应用程序,帽子对大量元素进行了一些排序(只有几行代码与数组操作)。

当我使用 F5 或 Ctrl-F5 从 Visual Studio IDE 启动发布代码时,程序比直接从 Win-Explorer 启动时慢约 3 倍。

41.140 seconds when launched from VS 2010 IDE
13.950 seconds when launched by double-clicking myprogram.exe

为什么???

4

4 回答 4

6

首先是一些细节...

请注意,.NET 中有两个主要的“优化”阶段。

  • 在 C# 编译器级别

    ...不同 IL(中间语言)的生成...优化或非优化...由您的项目是否设置DEBUG标志来控制

  • 在 JITer 级别

    ......当 IL 被翻译成机器代码(通过即时编译或通过 NGEN)......优化的机器代码可能会或可能不会生成

    注意:它不是通过生成的 IL控制 JITter 优化设置的 DEBUG 或 RELEASE 模式下的编译器......这是一个独立的设置。

主要的优化“胜利”发生在 JIT 级别。

当您通过 Visual Studio 调试 NET 程序时,通常您不希望 JITter 生成优化的机器代码,因为当您单步执行时,您的程序源语句不会与执行代码密切同步。

所以这就是为什么在 Visual Studio 中有一个选项可以关闭 JITter 优化(这相当于关闭带有AllowOptimize=0标志的 JITter 优化)......并且默认情况下 Visual Studio 会关闭 JITter 优化:

在此处输入图像描述

有关“抑制”选项的说明,请参见此处:

当您在 Visual Studio 之外运行 NET 应用程序时,该程序是编译为 DEBUG(未优化的 IL)还是 RELEASE(优化的 IL)都没有关系……默认情况下,JITter 将生成优化的机器代码。

因此需要注意的行为是,由于 JITter 优化设置不同,NET 程序在 Visual Studio 外部启动时比从 Visual Studio 启动时运行速度要快得多......即使它是 RELEASE 模式应用程序......as @ Knasterbax 观察到。此外,在调试 (F5) 时需要添加额外的开销,而不仅仅是从 Visual Studio 运行 (CTRL+F5)。

如果您从资源管理器运行您的应用程序(无论是 RELEASE 还是 DEBUG),然后您使用 Visual Studio“附加”到该进程,那么您的应用程序将使用正在应用优化的 JITter……您的代码将运行得更快……但任何源代码步进都不会同步。

如果取消选中“抑制 JIT 优化”,则可以在 Visual Studio 中以较差的调试体验为代价获得更快的执行速度。


最后,如果您需要/想要,有一种方法可以为您的应用程序代码关闭 JITter 优化:

  • 通过将其放入 app.config 禁用整个应用程序的 JITter

[.NET Framework 调试控件]
AllowOptimize=0

  • 您可以使用此属性告诉 JITter 不要优化指定的方法

[MethodImpl(MethodImplOptions.NoOptimization)]

在方法体上。

于 2012-10-09T12:02:07.597 回答
3

F5 是开始调试,而不是“运行”,它会做很多事情,比如在后台加载符号,即使你正在尝试调试发布版本。

于 2012-10-09T11:45:49.433 回答
2

启动带有调试器的程序总是比没有它时慢得多。

于 2012-10-09T11:45:40.253 回答
0

当您在调试模式下编译代码时,编译器会关闭一些优化,并添加一些额外的指令,以便可以在任何地方放置断点并可以单步执行代码。

这将使在调试模式下编译的代码比在发布模式下编译的代码慢。

于 2012-10-09T11:55:45.333 回答