为特定函数或代码块禁用编译器优化(C#)

38

编译器在优化发布版本时做得很好,但有时关闭本地函数的优化(而不是整个项目)是有用的,可以通过不选中 Project Options > Optimize code 来实现。

在 C++ 中,可以使用以下方法实现(其中 #pragma 通常被注释掉):

#pragma optimize( "", off )
// Some code such as a function (but not the whole project)
#pragma optimize( "", on )

在C#中有相应的等效方法吗?

更新

一些很好的答案建议使用MethodImplOptions.NoOptimization装饰该方法。这在.NET 3.5中已实现,但未在紧凑框架(CF)版本中实现。一个相关的后续问题是是否有类似于以下情况的等效方法:

  • 针对 .NET 3.0 或更早版本的项目?
  • 针对部署到设备(如使用 .NET 3.5 CF 的 Windows CE 6.0)的项目?
3个回答

56

你可以使用[MethodImpl(MethodImplOptions.NoOptimization)][MethodImpl(MethodImplOptions.NoInlining)]修饰特定的方法(或属性getter/setter),这会防止JITter优化和内联该方法:

[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
private void MethodWhichShouldNotBeOptimized()
{ }

然而,没有一种方法可以将这个属性应用于一段代码块。此外,在 .NET 3.5 中添加了 NoOptimization 属性,这对于遗留代码或紧凑框架可能很重要。


以前不知道这个选项,谢谢!我注意到 .NET 3.5 中添加了 MethodImplOptions.NoOptimization 枚举。你知道 3.0 或更早版本是否有相当的选项吗? - AlainD
@AlainD:不,.NET 3.0中没有这样的选项。他们在3.5中添加了“NoOptimization”,然后在4.5中添加了“AggressiveInlining”以强制内联某些情况。 - vgru
@Groo:好的,非常棒。非常有用的答案和评论。我在最近的一个项目中尝试过这个方法,它很有效,但是在必须使用CF(紧凑框架)的旧项目中无法使用。我将不得不寻找这个旧项目的替代方案。 - AlainD
@MartinBrown:.NET 3.5(https://msdn.microsoft.com/zh-cn/library/system.runtime.compilerservices.methodimploptions(v=vs.90).aspx)和.NET 3.0(https://msdn.microsoft.com/zh-cn/library/system.runtime.compilerservices.methodimploptions(v=vs.85).aspx)。小设备符号表示在紧凑框架中公开的内容。大多数开发人员使用完整版本的.NET(而不是CF),因此CF的限制并不相关。 - AlainD
@MartinBrown:嗯,这很奇怪。在一个独立的项目中,使用完整版本的.NET 2.0,NoOptimization标志是可用的(并且该项目可以编译),但内置帮助和MSDN在线都没有提及该标志的可用性。MSDN上的错误吗?可能非可移植版本只有CF才能使用? - AlainD
显示剩余2条评论

15
这是一个C#预处理器指令列表,但是没有C++的#pragma optimize的确切等效物。
然而,可以使用MethodImplAttribute并将其传递NoOptimizationMethodImplOptions来实现此操作,例如:
using System.Runtime.CompilerServices;

class MyClass
{
    [MethodImplAttribute(MethodImplOptions.NoOptimization)] 
    public void NonOptimizeMethod()
    {
        // Do some stuff
    }
}

7
在C#中,没有与#pragma指令相当的东西。你所能做的只是在方法范围内禁用。MethodImpl在System.Runtime.CompilerServices中。
[MethodImpl(MethodImplOptions.NoOptimization)]
void TargetMethod ()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接