What means "Non-inline to improve code quality as uncommon path" - c#

I was looking at source code of List and LargeArrayBuilder classes in .net core 3.0 and saw that method AddWithBufferAllocation marked by comment "Non-inline to improve code quality as uncommon path". Also, method has attribute MethodImpl with value MethodImplOptions.NoInlining. How does noinlining improve code quality?
I believe this degrades performance. I could be wrong, but the call method is the overhead of physically calling a method (call instruction) and passing parameters. Especially, if we use to value type.
sources

It improves performance in the general case when that if test is false and it doesn't make the method call at all.
It means that AddRange, that might make the method call (but rarely) is smaller and can be better optimised than the same method with, potentially, all of AddWithBufferAllocation inlined inside it.

Related

Virtual methods slower than nonvirtual methods to call

I have been reading up on virtual methods and how they are called. As discussed here and here, I have reached the conclusion that they should not really be that different.
The C# compiler emits IL code that calls static methods by the call IL instruction and calls virtual/non-virtual members by callvirt. It seems it is the job of JIT to actually figure out if the object the method being called from is actually null or not. So the check is the same for both.
Also, as discussed in the first article, it seems that vtables or tables that hold metadata on method definitions, are flattened at compile time. In other words, the tables contain exactly which method the object should call without a need for a recursive search up the inheritance chain.
With all the above, why are virtual methods considered slower? Is maybe one level of indirection(if any)that big of a deal? Please explain...
You're looking at the difference between a function call instruction with direct vs indirect addressing. But most of the "cost" of an indirect function call is not the call itself, but the lost opportunity to perform optimizations which require static knowledge of the target. Inlining, cross-procedure aliasing analysis, and so on.
Figuring out which actual method implementation to execute is going to have some cost, as opposed to just knowing. That cost can be very small, and it is quite likely that the cost is entirely negligible for any particular context because it really doesn't take that long. But the cost is non-zero, so in particularly performance sensitive applications it will make some difference.

Do I need to worry about inlining in Unity/C#? [duplicate]

This question already has an answer here:
AggressiveInlining doesn't exist
(1 answer)
Closed 5 years ago.
For code clarity I sometimes create a function that should very obviously be inlined, be it either a wrapper, or a function that is only called in a single point, or a short function that is supposed to be called frequently and be fast.
In C I would inline it without a second thought, but in Unity/C# there's no way to do that AFAIK (this appears to be only available at .NET 4.5).
Can I trust the compiler to be smart enough to actually inline smartly, or I'd better sometimes sacrifice code clarity for performance, mistrusting the compiler?
Sure it depends case by case, premature optimization is evil, and you should profile instead of guessing. However a general overview of this subject might still be useful as a guideline, to improve upon.
Manually forcing in-lining in C# at compile time doesn't make much sense. When the code is run the just-in-time compiler can decide to in-line the code based on these heuristics:
http://blogs.msdn.com/b/ericgu/archive/2004/01/29/64717.aspx
Methods that are greater than 32 bytes of IL will not be inlined.
Virtual functions are not inlined.
Methods that have complex flow control will not be in-lined. Complex flow control is any flow control other than if/then/else; in this case, switch or while.
Methods that contain exception-handling blocks are not inlined, though methods that throw exceptions are still candidates for inlining.
If any of the method's formal arguments are structs, the method will not be inlined.
If you're absolutely sure that the method has to be in-lined you can use these above heurstics to make the method more appealing to in-line.
MethodImplOptions.AggressiveInlining is mostly useful for inlining across assembly boundaries, something I do not believe the just-in-time compiler can do (but I'd have to check that).

Why is ToUpperInvariant() faster than ToLowerInvariant()?

I read in CLR via C# by Jeffrey Richter that String.ToUpperInvariant() is faster than String.ToLowerInvariant(). He says that this is because the FCL uses ToUpperInvariant to normalise strings, so the method is ultra-optimised. Running a couple quick tests on my machine, I concur that ToUpperInvariant() is indeed slightly faster.
My question is if anybody knows how the function is actually optimised on a technical level, and/or why the same optimisations were not applied to ToLowerInvariant() as well.
Concerning the "duplicate": The proposed "duplicate" question really doesn't provide an answer to my question. I understand the benefits of using ToUpperInvariant instead of ToLowerInvariant, but what I would like to know is how/why ToUpperInvariant performs better. This point is not addressed in the "duplicate".
Since it is now easier to read the CLR source which implements InternalChangeCaseString, we can see that it mostly calls down to the Win32 function LCMapStringEx. There appears to be no notes or any discussion on the performance of passing in LCMAP_UPPERCASE vs. LCMAP_LOWERCASE for the dwMapFlags parameter. Calling InternalChangeCaseString uses a flag isToUpper which, if true may result in better optimization by the compiler (or JITter), but since the call to LCMapStringEx has to setup a p/invoke call frame and the call itself has to do work, I'm not sure a lot of time is saved there.
Perhaps the recommendation is a hold over from some other implementation, but I can't see anything that would provide a significant speed advantage one way or the other.

Why aren't Automatic Properties inlined by default?

Being that properties are just methods under the hood, it's understandable that the performance of any logic they might perform may or may not improve performance - so it's understandable why the JIT needs to check if methods are worth inlining.
Automatic properties however (as far as I understand) cannot have any logic, and simply return or set the value of the underlying field. As far as I know, automatic properties are treated by the Compiler and the JIT just like any other methods.
(Everything below will rely on the assumption that the above paragraph is correct.)
Value Type properties show different behavior than the variable itself, but Reference Type properties supposedly should have the exact same behavior as direct access to the underlying variable.
// Automatic Properties Example
public Object MyObj { get; private set; }
Is there any case where automatic properties to Reference Types could show a performance hit by being inlined?
If not, what prevents either the Compiler or the JIT from automatically inlining them?
Note: I understand that the performance gain would probably be insignificant, especially when the JIT is likely to inline them anyway if used enough times - but small as the gain may be, it seems logical that such a seemingly simple optimization would be introduced regardless.
EDIT: The JIT compiler doesn't work in the way you think it does, which I guess is why you're probably not completely understanding what I was trying to convey above. I've quoted your comment below:
That is a different matter, but as far as I understand methods are only checked for being inline-worthy if they are called enough times. Not the mention that the checking itself is a performance hit. (Let the size of the performance hit be irrelevant for now.)
First, most, if not all, methods are checked to see if they can be inlined. Second, keep in mind that methods are only ever JITed once and it is during that one time that the JITer will determine if any methods called inside of it will be inlined. This can happen before any code is executed at all by your program. What makes a called method a good candidate for inlining?
The x86 JIT compiler (x64 and ia64 don't necessarily use the same optimization techniques) checks a few things to determine if a method is a good candidate for inlining, definitely not just the number of times it is called. The article lists things like if inlining will make the code smaller, if the call site will be executed a lot of times (ie in a loop), and others. Each method is optimized on its own, so the method may be inlined in one calling method but not in another, as in the example of a loop. These optimization heuristics are only available to JIT, the C# compiler just doesn't know: it's producing IL, not native code. There's a huge difference between them; native vs IL code size can be quite different.
To summarize, the C# compiler doesn't inline properties for performance reasons.
The jit compiler inlines most simple properties, including automatic properties. You can read more about how the JIT decides to inline method calls at this interesting blog post.
Well, the C# compiler doesn't inline any methods at all. I assume this is the case because of the way the CLR is designed. Each assembly is designed to be portable from machine to machine. A lot of times, you can change the internal behavior of a .NET assembly without having to recompile all the code, it can just be a drop in replacement (at least when types haven't changed). If the code were inlined, it breaks that (great, imo) design and you lose that luster.
Let's talk about inlining in C++ first. (Full disclosure, I haven't used C++ full time in a while, so I may be vague, my explanations rusty, or completely incorrect! I'm counting on my fellow SOers to correct and scold me)
The C++ inline keyword is like telling the compiler, "Hey man, I'd like you to inline this function, because I think it will improve performance". Unfortunately, it is only telling the compiler you'd prefer it inlined; it is not telling it that it must.
Perhaps at an earlier date, when compilers were less optimized than they are now, the compiler would more often than not compile that function inlined. However, as time went on and compilers grew smarter, the compiler writers discovered that in most cases, they were better at determining when a function should be inlined that the developer was. For those few cases where it wasn't, developers could use the seriouslybro_inlineme keyword (officially called __forceinline in VC++).
Now, why would the compiler writers do this? Well, inlining a function doesn't always mean increased performance. While it certainly can, it can also devastate your programs performance, if used incorrectly. For example, we all know one side effect of inlining code is increased code size, or "fat code syndrome" (disclaimer: not a real term). Why is "fat code syndrome" a problem? If you take a look at the article I linked above, it explains, among other things, memory is slow, and the bigger your code, the less likely it will fit in the fastest CPU cache (L1). Eventually it can only fit in memory, and then, inlining has done nothing. However, compilers know when these situations can happen, and do their best to prevent it.
Putting that together with your question, let's look at it this way: the C# compiler is like a developer writing code for the JIT compiler: the JIT is just smarter (but not a genius). It often knows when inlining will benefit or harm execution speed. "Senior developer" C# compiler doesn't have any idea how inlining a method call could benefit the runtime execution of your code, so it doesn't. I guess that actually means the C# compiler is smart, because it leaves the job of optimization to those who are better than it, in this case, the JIT compiler.
Automatic properties however (as far as I understand) cannot have any
logic, and simply return or set the value of the underlying field. As
far as I know, automatic properties are treated by the Compiler and
the JIT just like any other methods.
That automatic properties cannot have any logic is an implementation detail, there is not any special knowledge of that fact that is required for compilation. In fact, as you say auto properties are compiled down to method calls.
Suppose auto propes were inlined and the class and property are defined in a different assembly. This would mean that if the property implementation changes, you would have to recompile the application to see that change. That defeats using properties in the first place which should allow you to change the internal implementation without having to recompile the consuming application.
Automatic properties are just that - property get/set methods generated automatically. As result there is nothing special in IL for them. C# compiler by itself does very small number of optimizations.
As for reasons why not to inline - imagine your type is in a separate assembly hence you are free to change source of that assembly to have insanely complicated get/set for the property. As result compiler can't reason on complexity of the get/set code when it sees your automatic property first time while creating new assembly depending on your type.
As you've already noted in your question - "especially when the JIT is likely to inline them anyway" - this property methods will likely be inlined at JIT time.

CA2225: Operator overloads have named alternates

Good morning, afternoon or night,
Have you ever wrote anything in which Code Analysis popped up this kind of warnings? If so, did you pay attention to them and implement the friendly alternates? If so, using code repetition to avoid performance breakdowns or using operator calls?
Thank you very much.
If a method only contains a call to another method then most likely the outer method will be inlined into its caller. Which means that there is no performance loss. (Release build without debugger attached).
So I wouldn't duplicate the code and call the operators instead.
Personally I don't really get why the rule exists at all. Shouldn't languages without operator overloading support be able to just manually call the op_SomeThing public static method like any other method?
I do it on public classes of assemblies that are expected not to just see private use, and sometimes beyond that. Still, with one calling into the other, the overhead is negligible if indeed there is any overhead at all (I would expect inlining to mean the latter)

Categories

Resources