Does the JIT compiler optimize (inline) unnecessary variable declarations?

I read several articles and questions / answers that conclude that the best practice is to let the JIT compiler do all the optimization for calls to inline functions. Has the meaning.

What about inline variable declarations? Does their compiler optimize?

That is, whether it will be:

Dim h = (a + b + c) / 2 'Half-Perimeter If maxEdgeLength / (Math.Sqrt(h * (h - a) * (h - b) * (h - c)) / h) <= MaximumTriangleAspectRatio Then 'Do stuff here. End If 

Have better performance than this:

  Dim perimeter = a + b + c 'Perimeter Dim h = perimeter / 2 'Half-Perimeter Dim area = Math.Sqrt(h * (h - a) * (h - b) * (h - c)) 'Heron forumula. Dim inradius = area / h Dim aspectRatio = maxEdgeLength / inradius If aspectRatio <= MaximumTriangleAspectRatio Then 'Do stuff here. End If 

Of course, I prefer the latter because it is easier to read and debug, but I cannot afford the performance degradation if it exists.

Note. I have already identified this code as a bottleneck. No need for replicas about premature optimization. :-)

+8
performance c # inline
source share
2 answers

Temporary variables with names or not are not a problem.

But you can significantly optimize this inequality.

Your code:

 If maxEdgeLength / (Math.Sqrt(h * (h - a) * (h - b) * (h - c)) / h) <= MaximumTriangleAspectRatio Then 

Multiply both sides by the square root, excluding division (the inequality persists because the square root cannot return a negative number):

 If maxEdgeLength <= (Math.Sqrt(h * (h - a) * (h - b) * (h - c)) / h) * MaximumTriangleAspectRatio Then 

Now a square on both sides to eliminate this expensive square root:

 If maxEdgeLength * maxEdgeLength <= h * (h - a) * (h - b) * (h - c) / h / h * MaximumTriangleAspectRatio * MaximumTriangleAspectRatio Then 

Cancel and multiply by h .

 If maxEdgeLength * maxEdgeLength * h <= (h - a) * (h - b) * (h - c) * MaximumTriangleAspectRatio * MaximumTriangleAspectRatio Then 

It will be much faster. If this calculation is repeated, consider caching the results of part of this expression for further improvement.

Use comments to explain the formula. How to get rid of the Math.Sqrt call in the bottleneck function is to write an expression in a less simple format.

+16
source share

By the way, just to play the devil's advocate, I also wanted to point out this:

The JIT insert of the entire function looks at the length, in MSIL bytes, and not at the computational complexity. Adding local variables (and waiting for the JIT to register them) can increase the MSIL size for this function to make this function not a candidate for nesting.

This is unlikely to make a big difference in the quality of unnecessary use of Math.Sqrt , but it is possible. As Eric Lippert said, you will know more by actually measuring. However, such a measurement is valid for only one specific program launch and does not generalize to different processors or future versions of the .NET runtime (including service packs), which often change the behavior of JIT. Therefore, you need a combined analytical and empirical approach to optimization.

+5
source share

All Articles