In terms of memory and time, is it better to make a method static?
问题:
回答1:
Usually yes, there is no need to pass the "this" reference. That reference is passed in the ECX register so there is no additional stack space required. The register is already set if you make the call from an instance method of the same class, there will be no savings at all. But it can help relieving the pressure on a x86 CPU core when the method is in another class, x86 doesn't have a lot of registers. Seeing a measurable perf improvement would be exceedingly rare.
I do religiously mark methods of a class that don't use instance members as static. I value the inherent contract provided by the static keyword: "this method does not mutate the object state."
回答2:
You should make a method static if it does not require any state information from the class that it is part of.
If you don't care about polymorphism, you can write any method as either instance or static by just deciding whether to take class instance members and pass them to the method as arguments. What you should consider, is whether the syntax is natural, whether the code is easy to understand and meaningful, and so on.
You probably shouldn't worry about optimizing at this level, because the performance overhead of a instance vs. static method is negligible. Yes, there's some space used in the dispatch table for the type (if the method is virtual) - but it's a tiny, constant overhead. Yes, there's also a tiny overhead in invoking an instance method versus a static method - but again it's tiny.
This seems like a level of micro-optimization, that unless you have measurable, tangible evidence to believe is actually affecting program performance, you should avoid. In fact, if you do things wrong, the cost of passing in additional parameters (copying them onto the stack, etc) rather than accessing them through the hidden this
reference of your type, may result in worse performance.
You are better of analyzing the semantics of the method, and making the static/instance decision on that basis.
回答3:
If you are going to pass in the instance anyway (SomeStaticMethod(obj, "abc", 123);
), then not really. You could only usefully use a static method in a scenario without polymorphism, and in such cases it is highly likely that any simple things like properties would have been inlined anyway.
Use objects "naturally" (obj.SomeMethod("abc",123);
) - keep the code simple, and profile to find performance issues - it is very unlikely to be in the difference between instance and static unless you are running some very tight loops. There are some scenarios where it might matter, but they are pretty specialised.
回答4:
There is little to no difference between a static method and a non-virtual instance method. The latter just has the this
prointer/reference as a "hidden" argument. In the generated machine code, both kinds of calls look very similar.
A method should be static if it does not depend on/modify the object.
Virtual methods (overridable) on the other hand require the caller to look up the exact implementation in the so called vtable. In addition to preventing the compiler from inlining very small methods (simple property accessors are inlined very often) the lookup takes a couple of cycles.
Still, virtual methods are the fastest kind of dynamic dispatch available in C#/on the CLR. Much faster than delegates and reflection.
回答5:
There are many questions of this sort. Are static methods faster/slower? Are virtual functions faster/slower? Is i++ faster/slower than ++i? Is for(;;) faster/slower than while(true)?
It is worthwhile getting hold of some software and tuning it. That will give you a good sense of the kinds of things that actually affect software performance, in practice.
Then you will see that the answer to questions like that is (most of the time) that it is insignificant.
If I can generalize, the things that make software slow, in my experience, are the use of lines of code that look innocent but whose time consumption can be orders of magnitude larger than what might be imagined. Since they look innocent, they cannot reliably be found by looking at the code. Examples: Repeatedly allocating, initializing, and deallocating large data structures just to make sure they exist. Internationalizing strings that don't need to be. Notification-style programming that can turn a simple setting of a property into a massive cascade of method calls throughout a large data structure. Simple O(n^2) operations that would never have been a problem except that n got large. Thinking that (a < b) takes about the same length of time whether a and b are ints or big classes. This "time multiplication by looking innocent" has a compounding effect over multiple layers of abstraction, so large software tends to be riddled with it, in my experience.
回答6:
The difference is negligable in most cases, but static is more efficent.
The following steps are avoided in a static method call:
- Checking that the object reference (this) is not null.
- Finding the correct method on the virtual dispatch table.
- Placing the object reference on the stack.
回答7:
I find that many utility methods I write within a given class only need a few data members in the class, or none at all. In these cases, I tend to write those methods as (stand-alone) static methods, passing in directly the few data items that they need.
If they are particularly general and useful enough for other classes, I can make them public as well.