Reputation: 16513
I have a function that I use to add vectors, like this:
public static Vector AddVector(Vector v1, Vector v2)
{
return new Vector(
v1.X + v2.X,
v1.Y + v2.Y,
v1.Z + v2.Z);
}
Not very interesting. However, I overload the '+' operator for vectors and in the overload I call the AddVector function to avoid code duplication. I was curious whether this would result in two method calls or if it would be optimized at compile or JIT time. I found out that it did result in two method calls because I managed to gain 10% in total performance by duplicating the code of the AddVector as well as the dot product method in the '+' and '*' operator overload methods. Of course, this is a niche case because they get called tens of thousands of times per second, but I didn't expect this. I guess I expected the method to be inlined in the other, or something. And I suppose it's not just the overhead of the method call, but also the copying of the method arguments into the other method (they're structs).
It's no big deal, I can just duplicate the code (or perhaps just remove the AddVector method since I never call it directly) but it will nag me a lot in the future when I decide to create a method for something, like splitting up a large method into several smaller ones.
Upvotes: 4
Views: 504
Reputation: 12153
Theres only one optimization I can think of, maybe you want to have a vOut parameter, so you avoid the call to new() and hence reduce garbage collection - Of course, this depends entirely on what you are doing with the returned vector and if you need to persist it or not, and if you're running into garbage collection problems.
Upvotes: 0
Reputation: 16513
I had VS in Release mode and I ran without debugging so that can't be to blame. Running the .exe in the Release folder yields the same result. I have .NET 3.5 SP1 installed.
And whether or not I use structs depends on how many I create of something and how large it is when copying versus referencing.
Upvotes: 1
Reputation: 46496
Don't assume that struct
is the right choice for performance. The copying cost can be significant in some scenarios. Until you measure you don't know. Furthermore, struct
s have spooky behaviors, especially if they're mutable, but even if they're not.
In addition, what others have said is correct:
Upvotes: 1
Reputation: 163247
You say Vector
is a struct. According to a blog post from 2004, value types are a reason for not inlining a method. I don't know whether the rules have changed about that in the meantime.
Upvotes: 0
Reputation: 14162
If you compile into debug mode or begin the process with a debugger attatched (though you can add one later) then a large class of JIT optimisations, including inlining, won't happen.
Try re-running your tests by compiling it in Release mode and then running it without a debugger attatched (Ctrl+F5 in VS) and see if you see the optimisations you expected.
Upvotes: 5
Reputation: 18168
"And I suppose it's not just the overhead of the method call, but also the copying of the method arguments into the other method (they're structs)."
Why don't you test this out? Write a version of AddVector that takes a reference to two vector structs, instead of the structs themselves.
Upvotes: 3