views:

220

answers:

4

When, if ever, is it faster to pass arguments as arguments to a static method rather than have the method be non-static and access the same values via instance members. Assume the method accesses these members in a read-only fashion.

All other things being equal, calling a static method is slightly faster than calling an instance method.

All other things being equal, calling a method with no arguments is slightly faster than calling one with arguments.

Consider:

private Thing _thing;

void DoTheThing()
{
    _thing.DoIt();
}

Versus this equivalent code:

private Thing _thing;

// caller's responsibility to pass "_thing"
static void DoTheThing(Thing thing)
{
    thing.DoIt();
}

I can't think of a real-world situation where this kind of optimisation would really add any value, but as a thought experiment (for those who like to discuss this kind of thing), is there really a benefit, and if so then how many arguments (of what types etc) tip the balance the other way?

Would any other factors play into the consideration of this? The static method accesses _thing as a local variable rather than a field, for example.

+2  A: 

There's one possible performance benefit I can thnk of (for a non-virtual method): the static method doesn't need to test a reference for nullity first (to throw a NullReferenceException where appropriate).

I don't think this currently gives any advantage, but it's a possible one. I'm not sure it would apply in your particular example, though - and it's hard to see how it would apply in any case where you actually wanted to use the value.

Jon Skeet
A: 

In your case (I'm assuming the code sample would be in the Thing class) static and non-static will have no speed difference at all. This is from YOUR link:

  • 0.2 0.2 inlined static call
  • 0.2 0.2 inlined this inst call

So there is no sense at all in making it static for a speed boost.

Also take into account that the values provided in your linked page are from .Net 1.1 and way outdated.

Foxfire
An interesting point, though it only applies when methods are inlined. The example I used would probably be inlined but larger methods (or those with value types as arguments, IIRC) would not be inlined in which case the static call costs 6.1ns and the instance call costs 6.8ns.
Drew Noakes
According to the link you have the instance call would be 6.2ns instead of 6.1ns for the static. Also there are no numbers I would in fact assume that this would be overcompensated by the additional parameter which means that the static version is probably even slightly slower.
Foxfire
Just to clarify: It's a this instance call
Foxfire
@ Drew - Functions with value types as arguments get properly inlined as of .NET 3.5 SP1. @ Foxfire - Correct me if I'm wrong, but I think that an instance method has an implicit `this` reference passed to it as an argument, where it's explicit in the static method, but they both take 1 argument.
JulianR
I guess it might be an instance call. Thanks for pointing out that distinction as a factor.
Drew Noakes
@JulianR - I believe you're right. Instance calls pass the address of the target on the execution stack, at least in the IL model. What happens once the JIT has had its say is a different story. It may be that the target reference is already in en-registered, in which case it's not passed as such.
Drew Noakes
@JulianR likely correct. On the other hand as already stated I'd not take the concrete numbers literally anyways. As said they are outdated (Pentium III on .Net 1.1) and even the autor says they are very problematic. In fact they suggest that the fastest non-inlined method would be a virtual call (5.4ns)!! And everybody can see that this makes no sense for real applications.
Foxfire
@Drew Noakes Just as Info: Since .Net 3.5 Value Types are also inlined for the 32bit runtime (before they only were inlined on x64).
Foxfire
A: 

The use of statics will generally not improve your performance. The difference between static and instance is generally syntactic, and dispatching calls to a static member is hardly different than to an instance method. However,

if you do make methods static rather than instance, you will loose the option of method inlining. Static members are allocated on a special heap called a loader heap, and are not inlinable. Instance members, when built in release mode, may be inlined. Inlining increases the size of your executable, but completely eliminates any function call overhead. Back in the .NET 1.1 days (and probably still in .NET 2.0), methods up to 80k in size can be inlined. For methods that are frequently called, this can far outweigh the miniscul savings of a static call.

jrista
Thanks for your answer. Can you provide a reference for the fact that static methods are not inlined? The link I provided suggests that static methods can in fact be inlined.
Drew Noakes
Which link? My information may be older...it was based off an article on the internals of the .NET 1.1 CLR and JIT, which could have changed in .NET 2.0. Most things between the two runtimes have remained the same, but I know there have been some internal optimizations. If statics can indeed be inlined, then in the end, there really isn't any differnce between the two.
jrista
This link: http://msdn.microsoft.com/en-us/library/ms973852.aspx#fastmanagedcode%5Ftopic3 (sorry if it wasn't very obvious in the original question.)
Drew Noakes
Yeah, it appears statics can be inlined. I noticed in that list that the difference between static inline and this instance inline is nothing, they are both 0.2ns. Inlined methods from a different instance seem to take longer...but I wonder if that is an artifact of JIT...once inlined, I would figure the same execution time regardless of where the code came from.
jrista
Different instance calls are slower because the compiler needs to make a null check before invoking the method. If you call from the class you already know that it cannot be null.
Foxfire
@Foxfire: When a method is inlined, there is no other object. The code is duplicated locally...so there shouldn't be anything to check null on. I'm sure there is a reason for it, but I don't think it has to do with null checks.
jrista
A: 

I am not sure about the performance statics among static methods and instance methods.

But I believe that the decision should be taken whether you make it as a static method or instance method on the basis of object design. If by calling your method, the state of the object is not altered, then you should make that method as static method (method for the type, not for a perticular instance of the type).

123Developer