C # is not my director, but I may want to use some underlying tools to analyze the exception handling performance of C.
Here I have no intention to discuss the exceptions, good or bad, or when to use exceptions or not to use them. The exception handling mechanism of C # And windows is not discussed in depth. I just gave the test data to tell you whether the exception is slow or fast.
Both experiments use the same compiled EXE file. Both experiments use command line parameters to control whether to throw an exception and then collect data for comparison. I am too lazy to write the case where I do not use try catch or try catch but do not throw an exception. Of course, my experiment has no intention of proving the relationship between the overhead of exception handling and the overhead of the functokilltime I wrote. I just want to say that exception handling is slow.
LabCodeThe following is a simple ConsoleProgramThe compiling environment is WINXP SP3 + vs2008 SP1, the default release configuration.
Code
Namespace Vtuneexamplecsharp
{
Class Program
{
Static Int64 bignumber;
Static Void Functokilltime ()
{
For ( Int I = 0 ; I < 1000 ; ++ I)
{
Bignumber + = I * I;
}
}
Static Void Main ( String [] ARGs)
{
Bignumber = 0 ;
For ( Int I = 0 ; I < 100000 ; ++ I)
{
Try
{
Functokilltime ();
If (ARGs [ 0 ] = " Throw " )
{
Throw New Exception ( " An exception " );
}
}
Catch (Exception ERR ){}
}
System. Console. Write (bignumber );
}
}
}
Experiment 1 is made on my beloved win7 netbook. Its atom CPU has super threads, so from the operating system perspective, this is a dual-core CPU.
In this experiment, xperf is used to check whether an exception is thrown. Xperf is a performance debugging tool launched by Microsoft after Vista and has little impact on the system during runtime.
Figure 1 shows that when an exception is thrown, the execution time of the program is greatly increased.
This figure consists of the upper and lower parts, the upper part is the CPU usage, the two curves are dual-core, the lower part is the life cycle of the program, and the upper and lower parts of the X axis is time. It can be seen that when an exception is thrown (marked with a blue throw), the execution time is about 12 seconds without throwing an exception (marked with a blue no throw) the execution time is about 2 seconds.
Figure 2 uses xperf to observe which modules consume CPU resources. For example, in the throw scenario on the left (the program runs from 5 seconds to 17 seconds), I chose 8.6 ~ 14.5 seconds to observe the CPU usage.
We can see that vtuneexamplecsharp.exe occupies 49.97% (throw) and 44.13% (no throw) CPU resources, and most of the other resources are occupied by idle processes. This is because of dual-core, single-threaded program, cannot reach 100%
Vtuneexamplecsharp.exe is displayed in xperfstep, so you can observe the CPU resources occupied by each module. They add up to the CPU resources occupied by the entire program.
Here is the result I want to display. The proportion of all program resources occupied by each module when an exception is thrown is greatly different.
1. For example, in the case of no throw on the left, an unknown module occupies most of the CPU resources. The unknown module is basically equivalent to the code of the main function, including the functokilltime and throw operations, but the system handles the exception after throw. The reason for unknown is that xperf cannot parse the symbols file of the managed code for the moment. If the experiment uses C ++, you can see the specific module name, and even the functions in it.
2. The two moduleers with the value are ntkrnlpa.exe and mscorwks. dll. in the case of no throw, their overhead is basically 0. In the throw situation, the two of them are open and occupy the vast majority of the overhead of the entire vtuneexamplecsharp.exe. These two modules are the root cause of the dramatic performance reduction after throw.
(Note 1: I accidentally explain what ntkrnlpa.exe and mscorwks. dll are, and why an EXE can be used as another EXE module, which is not my Director)
(Note 2: The selected time period is not equal, so the total amount of program overhead is definitely different, so you cannot say that 8.97% of unknown is faster than 43.73% of unknown modules)
The conclusion in Experiment 1 is that if there is no throw, almost all CPUs are running the main function, and throw occurs, most CPU resources are occupied by other system modules to handle exceptions.
In experiment 2, I went back to my old WINXP SP3 development machine, which was equipped with the performance debugging artifact vtune.
Experiment 2 uses an executable file, which is the same as experiment 1. It also tests whether an exception is thrown or not thrown.
First, we post the original data and briefly explain the meaning of each column.
Module: Which different modules have been executed in the process space. Vtuneexamplecsharp.exe. JIT is the module of the Code compiled at the beginning.
Process: Which process belongs. Here I only pay attention to one process, so they are all the same.
The three columns instructions retired samples, instructions retired %, and instructions retired events indicate the total number of CPU commands executed by this module. Although the number of executed commands is not the same as the running time, it can still be used to reflect the program overhead.
First, there is no throw situation. We can see that the opening and sales of the tutorial is still vtuneexamplecsharp.exe. JIT, which is the same as the conclusion of Experiment 1.
(Mfeapfk. sys is my McAfee, which can be ignored)
In the case of throw.
1.vtuneexamplecsharp.exe. the total number of commands executed by JIT does not change much. For details, refer to the instructions retried samples and instructions retried events columns. The values of these two columns are absolute values, it directly reflects the number of commands executed by this module. It can be found that these values are slightly less than those without throw. Of course, this does not mean that the code is executed less in the case of throw, which is only the error of vtune sampling.
2.although the total number of executed commands of vtuneexamplecsharp.exe. JIT has not changed much, the proportion of the commands executed by the whole process has dropped significantly because other modules are handling exceptions.
A more intuitive chart based on the data is attached, indicating the percentage of the commands executed by each module to the commands executed by the entire program.
Again, the absolute values of the number of executed commands are different in the case of throw and no throw. In experiment 1, we can see that the running time is different, here we can see that the specific number of executions is different.
In the case of throw and no throw, the absolute value of the number of commands executed by the main module is compared. We can see that ntoskrnl.exe and mscorwks. dll are greatly increased, while the modules of the experiment code I wrote are basically unchanged. What is ntoskrnl.exe and mscorwks. dll? Why is it so much? I have no intention to explain it in detail here. This is not my director.
OK, the analysis is here. In fact, I have learned a little bit about it. These images are very intuitive.
------------------------------------------------------------------- I am bored with the split line ------------------------------------------------------------------------
Postscript and nonsense: It didn't take me long to experiment and draw conclusions, but it took a long time to process data, images, and write blogs.