Ivan
Thu Jul 31 01:39:27 CDT 2003
It depends vastly on the programming style you will be using.
Let's make a very simple example [see below, commented here].
In the first case you will have per each complete chain of operations
3 tests for the result code of your worker functions,
while in the second case there is no test if the contract is
that the worker function will throw when something bad has happened.
The resource cleanup is manual in the first case,
while it's 'embedded' in the objects in the second example.
In the first case the programer has to keep track of what is to be freed and
what not,
while in the second case the compiler takes care of the job.
The compiler can be smart about how to keep tral of partially constructed
objects,
while the programmer needs to test explicitely for some
IsReallWorthDestroying(MyResource),
that is often a test for NULL, unless it uses manually scopes.
The cost for keeping track of instances of classes in a given scope is to be
paid
no matter if the `if-succeeded-stair' is used or the `exception-safe-code'
style.
depending on compiler options, you may find that your code has the `call
XXXX!__EH_prolog'
[this is true for x86. for IA64 and AMD64 there is never an explicit prolog
for exception handling]
code in almost each function you've written, thus you are paying the same
cost of exception handling
even if you are not getting any benefit.
As a rule of thumb, you can assume that writing try/catch in your function
is not going to
affect the execution speed of your program.
Pedantically testing error codes instead of using exceptions may introduce
some
complexity in the generated code, and the mainstream code path may result
slower.
It's also true that dispatching an exception is not cheap.
The exception (synchronous with throw/RaiseException, async if you have
native exceptions)
needs one transition in kernel and one transition back to the exception
dispatcher code.
The exception dispatcher code MUST analyze each function on the stack for a
possible filter
wishing to recognized the exception (here I'm intentionally confusing native
exceptions and C++ exceptions as far as terminology is concerned), and as
soon as a filter is found,
if must unwind the stacks for all the encountered scopes.
Basically yur are paying in one shot the cleanup cost
that you would otherwise pay entering and leaving each scope,
plus one U-2-K transition (in the sync case) and one K-2-U transition.
To conclude, exception may lead to a more performant code if:
- they are really used for exceptional cases and not as a substitute of
error control.
- the places that throw the exception are very few (OS-level resource
allocators and nothing much shold throw)
- the places where the exception are caught are few (basically only at the
component boundaries)
- the rethrow paradigm is banned.
- the code is fully designed with exception in mind
(a function should always return void if any error is handled with
authomatic objects and exceptions).
Many may disagree with this, giving different circumstances where each
paradigm is superior
given a set of defined boundary condition. Hopefully I have been able to
give an overview of the problem.
if-SUCCEEDED-stair
HRESULT Funct() {
if (SUCCEEDED(Operation1(&Operation1Result))){
if (SUCCEEDED(Operation2(&Operation2Result))){
if (SUCCEEDED(Operation3(&Operation3Result))){
//
FreeResources(Operation3Result);
}
FreeResources(Operation2Result);
}
FreeResources(Operation1Result);
}
}
exception safe code
void Funct() {
OP_RES_1 Operation1(SomeParam);
Operation1.SomeMethod();
OP_RES_2 Operation2Result(SomeParam);
Operation2.SomeMethod();
OP_RES_3 Operation3Result(SomeParam);
Operation3.SomeMethod();
}
function invoker like
int main(int,char **){
try {
Funtc();
} catch (...) {
}
return 0;
}
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
"yonggeon kim" <ygkim@yujinrobot.com> wrote in message
news:#QhHejvVDHA.2104@TK2MSFTNGP10.phx.gbl...
> if used the try-catch context, the processing is more quick than not use?
>
>