Proposal C # 9: Module initializer

Module initializer proposal has been elevated to C # 9 candidacy. It's like C # static constructor, but it is not used in a class, but applied to the entire assembly.

This feature is present from the outset in the CLR, but until now have not been disclosed in C #. The initialization module is proposed, as it changes to the static constructor syntax disclosed.

[module: ModuleInitializer(typeof(MyModuleInitializer))]
internal static class MyModuleInitializer
{
static MyModuleInitializer()
{
// 将模块初始化器放在这里
}
}

Can be seen from this example, the module-level attributes are marked as the class name. Then, the static constructor for the class initializer is raised to the level of the module.
This feature may bring superior to ordinary static constructor performance. Mark Smeltzer wrote:

Currently, the use of init lock operation, has been processed for static configuration logic to double check. Even add a static read-only field to the class, it will immediately increase the cost of each external of any member of the class to use.

It can be guaranteed in a predictable sequence runs initialization logic, and no running after the initialization operation of the module, it will be a great advantage.

Another advantage is that the initialization module is predictable; wherein all code running order. For static constructors, from the point of view of assembly, their order is not running. Class B can be run before or after the client by the constructor code different class A.

For the above quotation, Mark Smeltzer has been clarified in the commentary:

Module initialization is still above-mentioned benefits, but at the time of the initial review, I did not notice .NET Core 3.0 hierarchical compilation of some of the latest improvements ...

Stratified compiled .NET Core 3.0+ solve the problem in a read-only access static members. For more information, please see the https://github.com/dotnet/coreclr/issues/24571#issuecomment-492401619. This feature has been released in .NET Core 3.0 version.

This feature is great: the initial fast compiler will generate, but not optimal runtime JIT code, if desired, and then execute it. Then, in the background, we analyze the context and IL code is run to determine whether the JIT can achieve better solutions. If so, it will re-compile the IL code, and replace the low-speed path JIT JIT optimal path. Of course, the realization of the process there will be some additional complexity, but this is the basic idea.

For static class initializer and static initializer read-only field, it will generate the first pass (first pass) with the initialization code for the lock operation. That prevents initialization run twice. The lock will also bring performance loss running. Therefore, once the initialization is run once, the optimizer will generate a new optimized access code path is no longer any locking!

Besides, I do not know the implementation details (I can confirm that the relevant track access is certainly very complex and need to be optimized after initialization), but net income considerable: automatically optimizes itself out using static initialization and static read-only runtime loss of performance of the field.

Terminology:

The .NET CLR "module" is a file containing the IL code. "Assembly" is a logical unit of one or more modules, one module is designated as the head assembly. Most .NET languages ​​are designed to create only a single module / single-file assembly. Therefore, for most developers, these terms are interchangeable.

VB in the "module" is the C # called "static class."

"Satellite assemblies" similar to the multi-module multi-file assembly / in some ways, but it is a separate concept.

Released 1535 original articles · won praise 586 · Views 2.37 million +

Guess you like

Origin blog.csdn.net/sD7O95O/article/details/104082303