我有一个非常简单的 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
为什么???
我有一个非常简单的 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
为什么???
首先是一些细节...
请注意,.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 优化:
[.NET Framework 调试控件]
AllowOptimize=0
[MethodImpl(MethodImplOptions.NoOptimization)]
在方法体上。
F5 是开始调试,而不是“运行”,它会做很多事情,比如在后台加载符号,即使你正在尝试调试发布版本。
启动带有调试器的程序总是比没有它时慢得多。
当您在调试模式下编译代码时,编译器会关闭一些优化,并添加一些额外的指令,以便可以在任何地方放置断点并可以单步执行代码。
这将使在调试模式下编译的代码比在发布模式下编译的代码慢。