Static vs. instance method: Which one performs better?

G

gnewsgroup

I am not sure if this question makes sense. But I have been wondering
if there is a performance difference between a static method and an
instance method.

I created something like this, just to give it a test.

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DateTime start = DateTime.Now;
Console.WriteLine(MyClass.GetString1());
DateTime end = DateTime.Now;
TimeSpan dur = end - start;
Console.WriteLine(dur.Milliseconds);

Console.WriteLine("#############");

start = DateTime.Now;
MyClass msc = new MyClass();
Console.WriteLine(msc.GetString2());
end = DateTime.Now;
dur = end - start;
Console.WriteLine(dur.Milliseconds);
}
}

class MyClass
{
public static string GetString1()
{
return "Just a junky string";
}
public string GetString2()
{
return "Just a junky string";
}
}
}

When I run it, I *always* a 0 duration for the instance method, but
for the static method, the duration is sometimes 0, sometimes 15 or
even larger.

I guess the task of the methods in the code above is too light to
yield any significant result. So, I am wondering, in general, if
there is a performance difference between a static method and an
instance method, assuming that they do exactly the same thing.

Anyone has an idea? Thank you.
 
J

Jon Skeet [C# MVP]

I guess the task of the methods in the code above is too light to
yield any significant result.

Definitely. Even if there *were* a difference, you'd have to call a
method millions or even *hundreds* of millions of times to see it.
So, I am wondering, in general, if
there is a performance difference between a static method and an
instance method, assuming that they do exactly the same thing.

Anyone has an idea? Thank you.

In theory a static method might be very, very, *very* slightly faster
- there's no "this" parameter to pass.

However, this should never *ever* be the deciding factor in whether or
not to make a method static.

Jon
 
G

gnewsgroup

Definitely. Even if there *were* a difference, you'd have to call a
method millions or even *hundreds* of millions of times to see it.



In theory a static method might be very, very, *very* slightly faster
- there's no "this" parameter to pass.

However, this should never *ever* be the deciding factor in whether or
not to make a method static.

Jon

Thank you. Yes, I am aware that there is a *justifiedness* issue in
choosing a static or instance method. Given what you say about their
performance difference, it seems that to be justified is more
important in this matter.
 
R

Rene

Jon,

I may be full of it (most likely) but I think I remember reading somewhere
that the compiler was able to detect if an instance function can be called
as a static function. If the compiler detected that this could be the case
then it would create the function call as a static call behind the scenes.

If that was the case then I guess the original question would be moot... but
then again, I wonder if I dreamed that I read that...
 
J

Jon Skeet [C# MVP]

Thank you. Yes, I am aware that there is a *justifiedness* issue in
choosing a static or instance method. Given what you say about their
performance difference, it seems that to be justified is more
important in this matter.

Taking the most "right by design" path is almost *always* the right
thing to do. Before you ever start bending the design out of shape,
measure the performance and see whether or not:
a) you actually have a problem
b) the change helps significantly

I can't remember the last time this was actually the case for me.

Jon
 
A

Arne Vajhøj

gnewsgroup said:
I am not sure if this question makes sense. But I have been wondering
if there is a performance difference between a static method and an
instance method.

I created something like this, just to give it a test.

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DateTime start = DateTime.Now;
Console.WriteLine(MyClass.GetString1());
DateTime end = DateTime.Now;
TimeSpan dur = end - start;
Console.WriteLine(dur.Milliseconds);

Console.WriteLine("#############");

start = DateTime.Now;
MyClass msc = new MyClass();
Console.WriteLine(msc.GetString2());
end = DateTime.Now;
dur = end - start;
Console.WriteLine(dur.Milliseconds);
}
}

class MyClass
{
public static string GetString1()
{
return "Just a junky string";
}
public string GetString2()
{
return "Just a junky string";
}
}
}

When I run it, I *always* a 0 duration for the instance method, but
for the static method, the duration is sometimes 0, sometimes 15 or
even larger.

I guess the task of the methods in the code above is too light to
yield any significant result. So, I am wondering, in general, if
there is a performance difference between a static method and an
instance method, assuming that they do exactly the same thing.

1) With almost certainty the difference does not matter.
2) I would expect static to be faster than instance.
3) Your test code is no good - Console.WriteLine will be much
more costly than the GetString's.

Arne
 
J

Jon Skeet [C# MVP]

Rene said:
I may be full of it (most likely) but I think I remember reading somewhere
that the compiler was able to detect if an instance function can be called
as a static function. If the compiler detected that this could be the case
then it would create the function call as a static call behind the scenes.

If that was the case then I guess the original question would be moot... but
then again, I wonder if I dreamed that I read that...

The C# compiler probably shouldn't do this, but the JIT compiler might,
yes. Not in debug mode though - you might print out "this" from the
debugger :)
 
M

Marc Gravell

Just some additional thoughts... your two methods both look like they
will be "inlined" by the JIT (they are very short, have no branching,
etc, and the instance method is neither virtual nor accessed through
an interface). So it is entirely possible thatt (in an optimised
build) neither actually involves a call *at all*!

For info, "fxcop" will highlight methods that don't depend on the
current instance and suggest making them static; that is the real
question: is it (now, or in the foreseeable future) specific to the
*current* instance, or is it a utility method.

Marc
 
J

Jeroen Mostert

gnewsgroup said:
I am not sure if this question makes sense. But I have been wondering
if there is a performance difference between a static method and an
instance method.
There is no way that you'll ever have a performance problem with this in
practice, so stop thinking about it. The difference is literally one extra
parameter to push on the stack.

If you do not use "this" in a method anywhere, then making it static may be
appropriate (not always -- it could be coincidence that you're not using
"this" right now, but will in the future, for example because it's a stub
implementation). If you do need "this", then making it static is impossible
without redesigning your class.

Redesign needs a damn good justification. "I will save one parameter on the
stack" is not good justification. You will not ever have any use for this as
a general optimization technique. I would say "if you ever profile the
application and see the problem is an instance method, you might consider
making it static" but even that's probably not justified, since there are
almost certainly better ways of optimizing.

Worrying about this is like worrying about the shape of the wing mirrors of
your car, because they might be slowing it down. You're wasting time you
should have been spending on the engine.
 
G

gnewsgroup

There is no way that you'll ever have a performance problem with this in
practice, so stop thinking about it. The difference is literally one extra
parameter to push on the stack.

If you do not use "this" in a method anywhere, then making itstaticmay be
appropriate (not always -- it could be coincidence that you're not using
"this" right now, but will in the future, for example because it's a stub
implementation). If you do need "this", then making itstaticis impossible
without redesigning your class.

Redesign needs a damn good justification. "I will save one parameter on the
stack" is not good justification. You will not ever have any use for this as
a general optimization technique. I would say "if you ever profile the
application and see the problem is an instance method, you might consider
making itstatic" but even that's probably not justified, since there are
almost certainly better ways of optimizing.

Worrying about this is like worrying about the shape of the wing mirrors of
your car, because they might be slowing it down. You're wasting time you
should have been spending on the engine.

Thank you all for the discussion. I am still pondering on the issue
of choosing between static and instance method.

Now that performance isn't even relevant in choosing a static or an
instance method, so, what's the decisive matter that justifies a
static method or instance method? What's wrong if the Math class were
implemented with a set of instance methods, and we do something like
below?

Math m = new Math();
double result = m.Pow(3.0, 2.0);
 
J

Jon Skeet [C# MVP]

Thank you all for the discussion. I am still pondering on the issue
of choosing between static and instance method.

Now that performance isn't even relevant in choosing a static or an
instance method, so, what's the decisive matter that justifies a
static method or instance method? What's wrong if the Math class were
implemented with a set of instance methods, and we do something like
below?

Math m = new Math();
double result = m.Pow(3.0, 2.0);

Well, does Pow depend in any way upon the instance of a Math? What
distinguishes one instance from another? Is there any sense in which
polymorphism is relevant? These are the questions to ask - the answer
usually comes from there.
 
J

Jeroen Mostert

gnewsgroup said:
Now that performance isn't even relevant in choosing a static or an
instance method, so, what's the decisive matter that justifies a
static method or instance method? What's wrong if the Math class were
implemented with a set of instance methods, and we do something like
below?

Math m = new Math();
double result = m.Pow(3.0, 2.0);

There's nothing wrong with it, except that everyone is forced to instantiate
a Math object that has no state -- it's really not much of an object at all.
There's literally nothing to distinguish two Math objects from each other
-- they might as well all *be* one object. So it's natural to make Math's
methods static, so that it effectively *is* one object. Saves typing and
possible initialization errors.

Now, compare this to the Random class, which is very similar to Math in
being a facility class. Random *does* have state -- the state of the random
number generator, on which the next generated number depends. If we made the
methods instance methods, we'd effectively force every client to share the
same Random state, which limits the usefulness of the class -- it makes it
impossible to generate a known sequence of numbers by seeding the generator,
for example. So Random has instances, even though most clients will reuse
the same instance as much as possible.

The vast majority of objects are distinct, having their own state, which
their methods modify. This is why the vast majority of methods are instance
methods. Static methods are used when there is no need for object state,
which occurs in a variety of circumstances:

- Facility classes without instances, like Math. Forcing the use of an
instance would have no benefits.

- Methods that construct or return object instances. A constructor can be
seen as a special kind of static method. More complex construction scenarios
may use a static factory method rather than a constructor, to enable
caching, for example. Encoding.GetEncoding() and XmlWriter.Create() are good
examples.

- Methods that operate on state shared between all instances of a class. The
canonical example is a method that returns a count of instances or that
increments an auto-generated ID, although neither has much practical
relevance. In .NET, these usually end up as properties rather than methods.
Methods that actually modify shared state often do so as part of a
construction pattern (see previous item) and are usually better off as
instance methods of a separate Factory class, because it gets hard to
understand quickly -- your class effectively becomes its own object.

- Methods that, by happenstance, do not need object state. For example, if
you decompose a complex method into separate functions, it may be that a
function does not operate on any object state, but only on its arguments. In
this case, making the function static may serve as an aid in maintaining and
debugging: you know that that method does not modify object state. This is
an implementation artifact, however, and should be reserved for private
methods (and they could be made instance methods whenever warranted).

This is not necessarily an exhaustive list, just what I can think of right
now. Like I said, instance methods are much more common, and you almost
never have to worry "do I need to make this method an instance method or a
static method" because it's usually dictated by purpose.
 
J

Jon Skeet [C# MVP]

Now, compare this to the Random class, which is very similar to Math in
being a facility class. Random *does* have state -- the state of the random
number generator, on which the next generated number depends. If we made the
methods instance methods, we'd effectively force every client to share the
same Random state, which limits the usefulness of the class -- it makes it
impossible to generate a known sequence of numbers by seeding the generator,
for example. So Random has instances, even though most clients will reuse
the same instance as much as possible.

Interestingly enough, for many uses of Random you really don't *need*
to be able to seed things, and a static, thread-safe form is much more
convenient - hence my StaticRandom class:

http://www.yoda.arachsys.com/csharp/miscutil/usage/staticrandom.html
 
J

Jeroen Mostert

Jon said:
Interestingly enough, for many uses of Random you really don't *need*
to be able to seed things, and a static, thread-safe form is much more
convenient - hence my StaticRandom class:

http://www.yoda.arachsys.com/csharp/miscutil/usage/staticrandom.html
I see you don't just use a Random instance per class because "it can be a
bit unsightly". That's true, but using a system-wide, thread-safe random
means you hit a lock every time any thread generates a random number. For
many applications that's fine, but it's not something you'd want in general.
Having things be a bit unsightly is usually preferable to a hidden
performance trap. I say "hidden" because I wouldn't expect people who use
this class to realize what they're really getting, they'd just go for the
convenience.

Of course, in case you'd really want to share a Random across particular
threads (as a functional demand, to share the same RNG sequence) you'd end
up with much the same class, but then it would at least be explicit.

Also, I'd like to use this opportunity to say that "MiscUtil" is a horribly
meaningless name, composed of horribly meaningless parts. I'd prefer
"JonSkeet". :)
 
J

Jon Skeet [C# MVP]

Jeroen Mostert said:
I see you don't just use a Random instance per class because "it can be a
bit unsightly". That's true, but using a system-wide, thread-safe random
means you hit a lock every time any thread generates a random number. For
many applications that's fine, but it's not something you'd want in general.

I'd say it's fine in general, but it's not something you'd want in a
few cases.
Having things be a bit unsightly is usually preferable to a hidden
performance trap. I say "hidden" because I wouldn't expect people who use
this class to realize what they're really getting, they'd just go for the
convenience.

On the other hand, it would be very obvious in a profiler - if it
proved to be a bottleneck.

In a few tests, I've found that on my box, when the lock is uncontested
it's a factor of 4 slower than a plain Random. When the lock is
contested that goes up to 5.

Yes, that's quite a slow-down - but it'll only be *significant* if
you're generating a heck of a lot of numbers. On my box, for instance,
generating 200 million numbers took about 20 seconds or so, using
StaticRandom. I suggest that there are relatively few applications
beyond mathematical simulations where that sort of "performance trap"
will be significant - and as I say, if it *is* significant, that will
be shown very quickly in a profiler.

There are plenty of trade-offs between convenience and performance. I
believe that in an awful lot of cases it's worth going for the more
convenient (and therefore usually easier-to-read) code until you have
some evidence that it's causing a significant performance issue.
Of course, in case you'd really want to share a Random across particular
threads (as a functional demand, to share the same RNG sequence) you'd end
up with much the same class, but then it would at least be explicit.

Also, I'd like to use this opportunity to say that "MiscUtil" is a horribly
meaningless name, composed of horribly meaningless parts. I'd prefer
"JonSkeet". :)

Yes, I've considered that before - although at that point it would
hardly endear itself to becoming a proper open source project, which is
one potential goal. (Marc Gravell has already supplied quite a lot of
code.)
 
M

Marc Gravell

Also, I'd like to use this opportunity to say that "MiscUtil" is a horribly
meaningless name, composed of horribly meaningless parts. I'd prefer
"JonSkeet". :)

Yes, I've considered that before [...]

Nah, we wouldn't want you to feel that we were "using" you... (waits
for the tumbleweed)

Marc
 
G

gnewsgroup

There's nothing wrong with it, except that everyone is forced to instantiate
a Math object that has no state -- it's really not much of an object at all.
  There's literally nothing to distinguish two Math objects from each other
-- they might as well all *be* one object. So it's natural to make Math's
methods static, so that it effectively *is* one object. Saves typing and
possible initialization errors.

I am aware that the common practice is to choose to implement a static
method if the notion of the entity does not have state such as Math.
When I was posting this yesterday, I was also wondering, if the only
purpose of static methods is to save typing. I would rather believe
that there is a stronger OO-related justification for choosing a
static method over an instance method, such as polymorphism, which Mr.
Jon Skeet mentioned in his reply.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top