[Switch] comparison of the execution efficiency between managed code and non-managed code
Worth reading
I. First, I would like to answer a question: is managed code (. NET) slower than unmanaged code (VC ++?
If you use the above question to ask everyone, basically everyone will answer it, and it will be slow! Are they correct? No, it is incorrect. The problem is that most people think. NET is just a Runtime Library-based framework, like Java or VB, or they even think. net uses virtual machine systems like Java. They did not take into account the program itself, did not take into account what the program is used for, and did not take into account the speed of access to the network or disk. Simply put, they do not think at all!
. NET is not like the Runtime Library (VB or Java ). It is a well-conceived framework in which Microsoft has made great efforts to ensure its good operation. In this article, I will show you some code that requires a lot of computation and compile it into hosted and unmanaged code. Then I will measure the performance of the two databases separately. You will see that it is not because the. Net program is automatically slower than the C ++ program. In fact, in some cases, the managed code is even faster than the unmanaged code.
Basically everyone knows that all. NET languages will be compiled into an intermediate language called Il assembly. However, many people do not know how the computer executes the intermediate code, or even understand it incorrectly.
JIT is an important part of. Net program running. The misunderstanding I just mentioned is that many people (definitely not a minority, I have asked many c ++ programmers, and there are 9 such ideas) JIT is actually something similar to Java VM. It is an interpreter that reads the Il assembly code at runtime and then simulates it into x86 code (also known as a virtual machine ). But in fact,. net uses more advanced technologies. After the. Net program is added to the memory, when a segment of IL code is run for the first time, the JIT compiler will compile the entire il code and then execute it. That's why the first time the. NET program was started slowly! With. net Library, Microsoft also comes with a tool, you can advance. all the Il code of the. NET program is compiled and stored in the cache. As a result, this program is exactly the same as that compiled by C ++, with no difference, the running time can also be separated from JIT (do not confuse it here, it is not to say that it can be separated. net Library, but does not need to be compiled in real time ). Therefore, do not confuse. NET and Java. The two operational efficiency is not a level at all!
Ii. experiment comparison
As a test algorithm, we select FFT (Fast Fourier Transform), an algorithm that converts time-related data (such as music) to its expected frequency information.
There are many types of algorithms. If you search by Google, you will find a lot of algorithms. Here I select real Discrete Fourier Transform, because it is relatively simple and easy to modify. I copied four copies to test the hosted C ++, C ++/CLI, and C #.
For unmanaged code, I just changed the function name to Fourier and added _ declspec (dllexport) for export.
The managed code changes slightly:
* The method parameter is changed to a hosted array, and array: length is used instead of the additional length parameter.
* Where trigonometric functions are involved, use the methods in the math class.
* Algorithms are exported as static members of a public class.
Then I converted the hosted C ++ code into C # And only made minor changes (most of them were syntactic and declarative changes)
Finally, I converted the hosted C ++ code into C ++/CLI
Then we will compile several different versions of all versions: unoptimized version, space optimization, and speed optimization.
Result:
I tested these programs on two computers, one with. NET 2.0 XP SP2 and the processor with piII 850,512 MB memory. The other one is vista build 5321, and the processor is 2 GHz mobile PIV and 1 GB memory. In each test, I take the average value of 100 algorithm operations. The result unit is millisecond, the following figure shows the running result of piII:
No optimization, space optimization, and Speed Optimization
Unmanaged 92.88 ± 0.09 88.23 ± 0.09 68.48 ± 0.03
Managed C ++ 72.89 ± 0.03 72.26 ± 0.04 71.35 ± 0.06
C ++/CLI 73.00 ± 0.05 72.32 ± 0.03 71.44 ± 0.04
C # managed 72.21 ± 0.04 69.97 ± 0.08
Results of the PIV computer:
No optimization, space optimization, and Speed Optimization
Unmanaged 45.2 ± 0.1 30.04 ± 0.04 23.06 ± 0.04
Managed C ++ 23.5 ± 0.1 23.17 ± 0.08 23.36 ± 0.07
C ++/CLI 23.5 ± 0.1 23.11 ± 0.07 23.80 ± 0.05
C # managed 23.7 ± 0.1 22.78 ± 0.03
It can be seen that the efficiency of the unmanaged code varies greatly in different optimization schemes. The optimization speed of the piII is 35% lower than that of the optimization, and the same is true for the PIV. This crude statistics shows that no matter which optimization scheme you choose, the management code is not very different in terms of running efficiency, and the compiler and connector do not affect the running efficiency, I will talk more about this information later.
It is strange that in Vista, the space optimization of Management Code is even faster than the speed optimization!
The result of C # is similar to the hosted C ++, but we can see that, the optimized C # code is faster than the optimized managed C ++ code.
Now let's compare the results of the following hosted and unmanaged code. Without optimization, managed code is much faster than unmanaged code. This gap is slightly shortened after the optimization space, unmanaged code is a little faster than hosted code. The difference between unmanaged code and C # code is only about 3%. However, C # code is still faster than C ++!
Iii. Mechanism Essence
The. NET Compiler (in this case, the hosted C ++ code) can be considered as equivalent to the parser engine of the non-hosted C ++ compiler. The compiler generates tables such as classes and methods, and then performs a series of high-level optimizations. . Net is actually a JIT (Real-Time compiler): This is where the program truly converts the code into x86 code of lower-level workers .. net compiler and JIT compilation are actually equivalent to the unmanaged C ++ compiler. The only difference is that ,. net is divided into two parts. in fact, when JIT runs the managed code. the. NET program is optimized for the customer's computer, rather than on the programmer's computer like the unmanaged code. The results show that the optimization settings of the hosted C ++ code and C # code have little impact. Obviously,C # code is at least as efficient as C ++ code.
Remember! In. net, no part is automatically slow in C ++ code,The efficiency depends entirely on the programmer.. Anyone who tells you that the managed code is slower than the unmanaged code is not taking into account the. NET runtime mechanism. Simply put, it is useless to. net!
I personally think that the compilation of C ++ (anyone who knows the principle of C ++ compilation knows) may involve optimization in the process of generating intermediate code or assembly code. There are two types of optimization: one kind of optimization only involves the Code itself, mainly deleting public expressions, loop optimization, code extraction, and useless code assignment.Another optimization design is specific computer hardware. For example, how to adjust and optimize the commands based on the features of the hardware execution commands, reduce the length of the target code, and improve the execution efficiency.This is non-hosted code. A bad result is that for different hardware clients, you must compile different versions in different compiling environments to achieve the best Optimization Efficiency.
However, for C #, JIT compilation will automatically optimize and compile the Il intermediate code based on the hardware environment (in fact, assembly code ).