16

Is there any difference regarding performance of private, protected, public and internal methods in C# class? I'm interested if one consumes more processor time or RAM.

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
Vadim
  • 1,223
  • 2
  • 17
  • 26
  • 2
    microptimisation anyone? – Mitch Wheat Sep 12 '11 at 08:16
  • 1
    Probably not, but there is a improvement (memory, I think) with sealed classes. – Jonathan Dickinson Sep 12 '11 at 08:18
  • 2
    What about `private static` (as opposed to non-`static`) methods? – Richard Ev Sep 12 '11 at 08:20
  • 1
    @Jonathan Dickinson: I'd expect it to be a potential virtual member optimization, where the JIT compiler *knows* that even a virtual method isn't going to be overridden any further. – Jon Skeet Sep 12 '11 at 08:21
  • @Jon there is a obfuscator that **claims** improved speed/memory, and its primary method of achieving that is sealing non-inherited internal classes (because it knows they can 'never' be subclassed) - I am not sure of the JIT specifics though. – Jonathan Dickinson Sep 12 '11 at 08:26
  • @Richard - making methods that don't refer to `this` `static` is part of the Microsoft.Performance FXCop ruleset; so I assume it does make a difference. – Jonathan Dickinson Sep 12 '11 at 08:26
  • Mitch Wheat: no, just was looking for similar question in the net and haven't found anything, and for C# and .NET I thought I would ask if something is going on behind the scenes when calling the methods with different access modifiers. – Vadim Sep 12 '11 at 08:29
  • The only access modifiers that improve performance are *static* and *sealed*. In both cases the compiler can either skip the vtable lookup, or in the case of sealed methods/classes, take a big shortcut to the top of it :) – MattDavey Sep 12 '11 at 08:33

2 Answers2

9

I'm not aware of any performance difference for normal invocation; it's possible that more restricted access will take a little more work when accessing via dynamic invocation or reflection as the caller may need to be validated more carefully. In the normal JIT-compiled case the access can be validated by the CLR just once and then taken for granted. I guess it's possible that the JIT compilation (and IL verification) itself could be slightly slower for more restrictive access - but I find it hard to believe it would be significant.

This should absolutely not be a factor in determining which accessibility to use, even if somehow there is some tiny performance difference I'm unaware of. If you believe you may be able to achieve a performance benefit by making the accessibility something other than the "natural" one for your design, you should definitely benchmark the before/after case - I suspect you'll be hard-pressed to find a real-world situation where the difference is reliably measurable.

The same sort of advice goes for all kinds of micro-optimization: it's almost never a good idea anyway, and should definitely only be undertaken within careful measuring.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    I'm surprised that you weren't more unequivocal. Having said that, I was in the process of elaborating on "No". – harpo Sep 12 '11 at 08:16
  • 2
    wouldn't private methods perhaps be optimized (inlined, e.g.) more aggressively by the JIT engine? – sehe Sep 12 '11 at 08:16
  • @sehe: Why would you think that? Even if a method is public, it can't change after JIT compilation... – Jon Skeet Sep 12 '11 at 08:18
  • @sehe - I don't think so. It's cross-ngen boundary or not, so if you call a `public` method from the **same assembly** it will get inlined just as agressively as a `private` one; the only way to get cross-ngen-boundary inlining is with [`TargettedPatchingOptOutAttribute`](http://msdn.microsoft.com/en-us/library/system.runtime.targetedpatchingoptoutattribute.aspx). – Jonathan Dickinson Sep 12 '11 at 08:20
  • 1
    @Jon: well, I wasn't thinking of modification (urgh?) but rather pragmatism: as soon as the compiler knows a method should be externally available, it might decide not to inline it at all in the interest of reducing code size? I was simply contemplating this, hoping you had a ready answer :) – sehe Sep 12 '11 at 08:23
  • @Jonathan: that's interesting stuff. (_However, about Targeted Patching: on reading [backgrounds](http://blogs.msdn.com/b/clrcodegeneration/archive/2009/05/03/improvements-to-ngen-in-.net-framework-4.aspx) it would seem that would only apply to Framework Libraries (and we don't get to call any private methods from them anyway)_) – sehe Sep 12 '11 at 08:27
  • @sehe: I'm not *aware* of the JIT inliner taking this approach, but it's possible I guess.... – Jon Skeet Sep 12 '11 at 08:31
  • @sehe: no it really does work with non-Framework Libraries; although it will increase the ngen time of any dependencies - it also only makes a difference with public methods (it basically allows them to get inlined into an ngen image for another assembly); and only does something if you ngen the assembly. – Jonathan Dickinson Sep 12 '11 at 08:31
  • 1
    Ok, so the lowdown is: it _might_ make _teeny tiny_ bits of difference, but the chances are exceptionally small, as the JIT optimizer appears to be more aggressive (... than I would have expected for a VM-based jitter) in that public methods are eligible for inlining within assemblies. – sehe Sep 12 '11 at 08:33
0

There will be no measurable difference in performance between private, protected or public methods.

If you focus on optimization, possibly you should try making your bottleneck piece of code more "procedural" than object-oriented. It would do small improvement.

Chris W
  • 1,562
  • 20
  • 27