I don't believe the generated code would check if the class has been initialized everytime it access a static member (which includes functions). I believe checking every access would be inefficient. I looked at ยง17.11 in ECMA 334 and it says
The execution of a static constructor is triggered by the first of
the following events to occur within an application domain:
An instance of the class is created.
Any of the static members of the class are referenced.
It looks like how to figure out when 'first' happens is not defined. I can't think of any way to do it but to check every time. How might it be done?
When you have a problem to solve, a good technique is: solve an even harder problem, such that the solution of your small problem is solved by the solution of the harder problem.
The CLR has a much harder problem to solve: it has to run the jitter exactly once on every method right before the method is called for the first time. If the CLR can solve that problem, then it can obviously solve the comparatively trivial sub-problem of detecting when a static ctor needs to run.
Perhaps your question should then be "how does the jitter know when to jit a method for the first time?"
When you are generating code at runtime, you have lots of options. You can call a NULL function pointer, catch the access violation, run the static constructor, compile the property getter, update the function pointer, and continue. Or have the property getter call a helper function that runs the static constructor and rewrites the getter code without the helper function call. Or insert a check on every static member access, that when hit recompiles the calling function with the check removed.
Related
My question is why the described solution to problem below works.
Intro: I have a small c++ server application, that does its business logic in c#. I use DllExport for the (reverse) pinvoke. All is peachy, everything is fast, stable, no leaks or any issue.
C# is composed of several assemblies(all is 4.7.2, x64 as is native), but i keep exports only in one.
Problem: One part of development led me to call a trivial utility public static function from another assembly that only contains a single file with single static class with about 15 helper functions and a single interface
public interface ISerializable
{
BinaryWriter serial(BinaryWriter w);
//ISerializable serial(BinaryReader w);//itself
}
When debugger hits the function, it immediately threw null pointer exception and when i hit continue, it threw FatalExecutionEngineError. The exception happens as the function is called, before anything else happens. When looking at assembly debugger, it happens on the CALL instruction. Again, there were no stack issues or anything untoward.
Things i tried:
Being paranoid about eliminating mistakes on my part, i created an clean call pinvoke that internally only called a simple test function doing nothing from the same class.
It crashed immediately.
When i moved this test function to new static class in the same assembly, it worked....
What worked: Out of desperation, i moved the interface to a separate static class and everything started to work.
Obviously, this is a cargo cult coding and i would like to understand how to debug the issue. How in theory could the dllexport/pinvoke cause this this bug? Anyone seen anything similar?
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.
I am creating an interpreted programming language in C# (kind of for the lulz, no real purpose other than to have fun and learn about compilers), and ran into a problem. In my lexer, I remember where the token was in the original file to give more useful debug errors. I keep this "TokenPosition" object around, copying it along as the program goes through compile steps, until it winds up in the same object that runs interpreted code (for example, my "Identifier" class for named variables has a TokenPosition member).
My question: If an exception gets thrown, I want to look at the stack, find the topmost object with a TokenPosition member, and print its location. Or, more generally, "How do I get objects that are/were on the stack after an exception? Is this even possible?" (I can do the checking if it has a TokenPosition object / getting it easily, I'm not asking how to do that)
Last resorts that I do not want to have to do: Every single call to a behavior (which happens A LOT) assign a static tokenPosition variable somewhere with this.tokenPosition. I also could surround EVERYTHING with try/catches, but again, I don't really want to do this.
Parameters to methods are ephemeral. They may be overwritten by local variables when they are no longer live, or optimized out by the JIT compiler as unused, or even garbage collected while the method is running. You will have to track this information yourself, for example, by having a separate stack data structure for "currently active object" that is automatically unwound by a using clause.
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)
I assume that public or private static targets must have reduced memory usage, due to the fact that there is only one copy of the static target in memory.
It seems like because a method is static that might make the method a potential point for further optimization by the CLR compiler beyond what is possible with a non-static function. Just a flimsy theory though, so I've come to ask you all.
Do static public or private methods provide any increased performance benefit beyond reduced memory usage?
(Note: I'm not interested in responses that talk on the problems of premature optimization. Certainly that's sound advice I follow everyday, but that does not mean optimization is not necessary at times. (double negative!). Allow me to indulge my curiosity, at the least)
From Static Classes and Static Class Members (C# Programming Guide)
A call to a static method generates a
call instruction in Microsoft
intermediate language (MSIL), whereas
a call to an instance method generates
a callvirt instruction, which also
checks for a null object references.
However, most of the time the
performance difference between the two
is not significant.
Aside from what astander said, your question suggests a misunderstanding of what instance methods do. Regardless of whether the function is static or not, there is only one copy of the function code in memory. A non-static method has to be called through an object, but the object does not carry its own private copy of the method. So the memory usage of static and non-static methods is in fact identical, and as others have pointed out, the performance characteristics are nearly identical.
Non-static member variables, however, do exist separately for every object that you create. But it is nearly always a waste of time to worry about that memory usage, unless you actually have a memory-related problem in your program.
This is a little bit off-topic, but none the less important.
The choice of making methods static or instance should not be based on execution time (which anyway seems not to matter). It should be based on whether the method operates on an object. For instance, all the Math.* methods are static while e.g. (most) String.* methods are instance since they operate on a String instance. My personal philosophy: a good design should make up for the few cycles that may be saved elsewhere.
Another view on the subject: I recently worked with a guy who had been told that static methods are evil because they take us back to the dark age of procedural programming and thus shall be avoided at all costs. This resulted in weird examples of classes that required instances for access to methods that had absolutely no interest in the internals of the object.
Phew, it felt good to get that from my hearth.
Good answers - basically it doesn't matter, which is the answer to nearly every question of this sort. Even if it did make a difference - If execution time of your program cost a dollar, this sort of issue is likely to cost a fraction of a cent, and it is very likely that there are other things costing a great deal more.
MeasureIt to be certain, but you'll find unless you're creating a globe-spanning ultra-high-volume transaction processing supercomputing cluster, it's not going have an appreciable difference.