Exception handling is a very esoteric topic, and this is just about the impact it has on C + + performance.
In VC + +, there are multiple exception handling modes, three of the most important:
- No exception handling (no exception handling)
- C + + only (c + + language exception handling)
- C + + SEH (c + + language plus Windows Fabric exception handling mechanism)
Each additional level of exception handling has to pay a price in time and space. We start with the following simple C + + example to analyze the principle of exception handling and its performance:
Simple class
Class Myappobject
{
Public
Myappobject (int id): _myid (ID) {}
~myappobject ();
int _myid;
void dosomething (int throwwhat);
};
Can throw 2 different exception
void Myappobject::D osomething (int throwwhat)
{
printf ("Myappobject::D osomething called for '%d ' \ n", _myid);
Switch (throwwhat)
{
Case 0:
Break
Case 1:
This->_myid/= 0; //exception 1
Break
Case 2:
Throw simplestring ("error!"); //Exception 2
Break
}
}
Test exception for the above class
void Testmyappobject()
{
printf ("before try");
Try// line1
{
printf ("Intry");
Myappobject so = 1; line2
Simplestring SS("Test ex point One"); Line3
So. DoSomething (1); line4
printf ("So::id called for '%d ' \ n", So._myid);
Myappobject SO2 = 2; Line5
printf ("So2::id called for '%d ' \ n", So2._myid);
SO2. DoSomething (0); Line6
}
catch (const simplestring &e)// Line7
{
printf ("Something happened:%s \ n", e);
}
catch (...) Line8
{
printf ("Something happened:%s \ n", "SEH");
}
}
The first step , we first select "No exception", and the above line1, Line7, Line8 commented out. The size of the code is:
Exe |
Obj |
32,256 bytes |
20,931 bytes |
However, because line4 introduces a "except 0" exception, our program stops working abnormally. This is no big disaster. But if this is a critical server program, the results will certainly not be acceptable to the customer.
In the second step , we chose C + + only flag (/EHSC). The code size changes to:
Exe |
Obj |
37,888 bytes |
24,959 bytes |
Code size more recent than the previous selection 20% .
However, this choice determines the exception we can capture if the throw of C + + is generated. Exceptions generated by the operating system, such as exceptions generated by the Windows SEH exception mechanism, cannot be captured. When testing, line1,line7,Line8 comments are canceled.
Running the program, the " except 0" Exception still causes the program to stop. However, when the line4 input is changed to 2 o'clock, the exception ofC + + throw is Line7 captured.
In the third step, we select "C + + SHE (/EHa)" and the code size changes to:
Exe |
Obj |
37.0 KB (37,888 bytes) |
28,486 bytes |
The code obj size changes slightly, but not significantly. After choosing this, Myappobject: Two anomalies of:D osomething can be captured.
Exception handling semantics
With exception handling, the program's "Working set (Working Set)", with a growth rate of up to 20%, is quite significant. Key software components must take this into account. So, will the speed of operation be affected? Let's look at the semantics of exception handling first.
In the above Testmyappobject , because C + + must be guaranteed to "correctly" destroy automatic variables, such as Testmyappobject , in the case of an exception, theSS , and SO2 variables. In the case of exception handling, it is necessary to distinguish between " area " and " hotspot " of " Current program ".
For example, thetestmyappobject area has before try and in try.
testmyappobject hotspots have line2 ~ Line6 (each line is a hotspot).
The logic for testmyappobject exception handling is:
- If the line2 is out of the ordinary, there is no need to do anything (unless there are some myappobject members partially constructed member problem).
- If the line3 is abnormal , so must be destroyed.
- If the line4 is abnormal , both so and SS must be destroyed.
- If the line6 is abnormal, so,SS, and SO2 must be destroyed.
VC + + implementations are roughly the same:
The exception handling logic can be converted into a static Jump List (listing the jump to address of the four hotspots above), and a stack_unwind () function (the stack rollback function ), from this list, dynamically jumps to the rollback code in the exception, based on the current "hot spot".
Combined, exception Handling in C + +, depending on the distribution of the function's auto variable, the appeal Jump List must be added to each function that may appear to be abnormal, resulting in a noticeable increase in the size and working set of the program. However, the test shows that if there is no exception, the effect of the execution speed of the program is negligible (just need to keep the hotspot location), and thetestmyappobject test Result chooses exception handling (but not exception) rather than choosing to not support exception handling slightly faster.
After the abnormal,testmyappobject test results show that the effect of the program speed can be more than 10%~15%. But my test has not added rethrow Other exception handling logic, just capture it.
Another interesting problem is that the distribution of the auto variable in the function, the effect on the "Hot List" size, too many hotspots, will cause the hotspot list to become large, so if possible, try to put the auto variable at the top:
X a , b ;
Y C , D ;
Instead of
X a ;
//Do something (1 )
X b;
//do something else (2 )
Y C;
//Do yet something else (3 )
Y D;
Because the first distribution has only one hotspot (assuming that constructor does not throw). The second distribution has at least three hotspots.
Summarize
Exception handling is a language construct with significant added value in C + +, providing a cornerstone for secure and reliable applications.
But it also has the time and space cost (tradeoff), we need to understand this aspect in the application. Exceptions should be used in " Abnormal Time " (as if it were nonsense, in fact, an important part of design ideas and patterns), and do not use it as a convenient "control construct". If the application allows, also minimize "hot spots", reduce the list of hotspots.
On semantics and performance of C + + exception handling