37

The compiler does a great job of optimising for RELEASE builds, but occasionally it can be useful to ensure that optimisation is turned off for a local function (but not the entire project by unticking Project Options > Optimize code).

In C++ this is achieved using the following (with the #pragma normally commented out):

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

Is there an equivalent in C#?

UPDATE

Several excellent answers suggest decorating the method with MethodImplOptions.NoOptimization. This was implemented in .NET 3.5, though not in the Compact Framework (CF) version. A related follow-on question is whether there is an equivalent for:

  • projects targeting .NET 3.0 or earlier?
  • projects deployed to a device such as Windows CE 6.0 using the .NET 3.5 CF?
RBarryYoung
  • 55,398
  • 14
  • 96
  • 137
AlainD
  • 5,413
  • 6
  • 45
  • 99

3 Answers3

55

You can decorate a specific method (or a property getter/setter) with [MethodImpl(MethodImplOptions.NoOptimization)] and [MethodImpl(MethodImplOptions.NoInlining)], this will prevent the JITter from optimizing and inlining the method:

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

However, there isn't a way to apply this attribute to a block of code. Also NoOptimization attribute was added in .NET 3.5, which might be important for legacy code or Compact Framework.

vgru
  • 49,838
  • 16
  • 120
  • 201
  • Never knew about this option, thanks! I note that the `MethodImplOptions.NoOptimization` enumeration was added in .NET 3.5. Do you know if there is an equivalent for versions 3.0 or earlier? – AlainD Jul 28 '16 at 10:08
  • @AlainD: No, there wasn't such option in .NET 3.0. They added `NoOptimization` in 3.5, and then `AggressiveInlining` in 4.5 for forcing inlining in some situations. – vgru Jul 28 '16 at 10:21
  • @Groo: OK, great. Very useful answer and comments. Have tried this on a recent project and it works, but not in an older project that must use the CF (compact framework). Will have to look for an alternative for this older project. – AlainD Jul 28 '16 at 10:28
  • @MartinBrown: .NET 3.5 (https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimploptions(v=vs.90).aspx) and .NET 3.0 (https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimploptions(v=vs.85).aspx). The little device symbol indicates what is exposed in the Compact Framework, BTW. Most developers use the full version of .NET (and not CF) so the limitations of the CF are not relevant. – AlainD Jul 28 '16 at 10:31
  • @MartinBrown: Hmm, this is weird. In a separate project, using the full version of .NET 2.0 the `NoOptimization` flag is available (and the project compiles) but neither the in-built help nor MSDN online mention the availability of the flag. Bug in MSDN? Possibly the non-availability is restricted to the CF only then? – AlainD Jul 28 '16 at 10:36
  • I had selected the full framework by mistake. I don't have old versions of the compact framework to test against. – Martin Brown Jul 28 '16 at 10:47
  • @AlainD: I can no longer remember whether I used this in .NET 2 and I am pretty sure source code for the .NET 2 JITter cannot be found anywhere (it certainly wasn't open source), so the only way I can think of (if you are really able to compile it) would be to check the release-version disassembly for the version with this flag. Since these are bit flags, it the old compiler doesn't support a value, it will probably just ignore it while testing for known flags, but there is also a possibility this is simply missing from MSDN. – vgru Jul 28 '16 at 11:02
15

Here is a list of C# Preprocessor Directives but there is no exact equivalent to the C++ #pragma optimize.

However, it is possible to do this using the MethodImplAttribute and passing it the NoOptimization MethodImplOptions like this:

using System.Runtime.CompilerServices;

class MyClass
{
    [MethodImplAttribute(MethodImplOptions.NoOptimization)] 
    public void NonOptimizeMethod()
    {
        // Do some stuff
    }
}
Martin Brown
  • 24,692
  • 14
  • 77
  • 122
7

In c# there is no equivalent to #pragma directive. All you can do is method scope disable. MethodImpl is in System.Runtime.CompilerServices.

[MethodImpl(MethodImplOptions.NoOptimization)]
void TargetMethod ()
VitaliyK
  • 279
  • 1
  • 8