Layers and exceptions
-
Thanks for your reply. Yes everything you do slows things down, but Stroustrup points out that in C++ exception handling adds a lot of time -- far more than error handling. In the interpreted languages, it likely makes less difference due to their already sluggish behavior. If exceptions are used only for truly exceptional situations, then the performance impact may be negligible. In an earlier generation of HP compilers, there was a 25% overhead if you turned on exceptions in our application that accessed multi-gigabyte data sets. The problem turned out to be that loop unrolling didn't work as well with exceptions turned on. However HP has fixed this problem and you only get about a 5% overhead. However, if you have a big supply chain planning application that takes 12 hours to run, that 5 percent matters. Yes, exceptions can be mis-used like many other features. But some features are more prone to mis-use than others. Exceptions anre an institutionalized laziness. They give the developer the idea that exception handling is someone else's problem, I just have to report the problem. And low and behold, every problem becomes worthy of an exception. Why should I have to do that grunt work? Yep, error codes can be easily ignored. But so can exceptions: you just catch(...) and do nothing.
Lowell Boggs wrote:
Yes everything you do slows things down, but Stroustrup points out that in C++ exception handling adds a lot of time -- far more than error handling.
I suspect you will find there is less of an impact now.
Lowell Boggs wrote:
if you turned on exceptions in our application that accessed multi-gigabyte data sets.
I would guess that such a situation happens very rarely in a correctly written application. I have seen people who were trying to code to the idea that they were going to return gigabytes of data to a user list boxes - problems like that however have nothing to do with problems inherit in exceptions themselves.
Lowell Boggs wrote:
However, if you have a big supply chain planning application that takes 12 hours to run, that 5 percent matters.
And how many exceptional conditions do you plan on handling in that? I have written batch applications that took hours to process and errors, not exceptions, were common. Which doesn't mean that exceptions, for exceptional conditions, did not exist but they were very rare. So exceptions even if they were expensive wouldn't have matter.
Lowell Boggs wrote:
They give the developer the idea that exception handling is someone else's problem, I just have to report the problem.
And do error values help when the developer doesn't address exceptional conditions using any mechanism? Does it help when the developer returns 1000 different errors codes? Error codes do not magically allow for a correct solution.
-
Lowell Boggs wrote:
Yes everything you do slows things down, but Stroustrup points out that in C++ exception handling adds a lot of time -- far more than error handling.
I suspect you will find there is less of an impact now.
Lowell Boggs wrote:
if you turned on exceptions in our application that accessed multi-gigabyte data sets.
I would guess that such a situation happens very rarely in a correctly written application. I have seen people who were trying to code to the idea that they were going to return gigabytes of data to a user list boxes - problems like that however have nothing to do with problems inherit in exceptions themselves.
Lowell Boggs wrote:
However, if you have a big supply chain planning application that takes 12 hours to run, that 5 percent matters.
And how many exceptional conditions do you plan on handling in that? I have written batch applications that took hours to process and errors, not exceptions, were common. Which doesn't mean that exceptions, for exceptional conditions, did not exist but they were very rare. So exceptions even if they were expensive wouldn't have matter.
Lowell Boggs wrote:
They give the developer the idea that exception handling is someone else's problem, I just have to report the problem.
And do error values help when the developer doesn't address exceptional conditions using any mechanism? Does it help when the developer returns 1000 different errors codes? Error codes do not magically allow for a correct solution.
I agree completely that there is no magic solution. As for my comments about exceptions slowing things down, I have measured it myself with several compilers. Merely compiling with exceptions turned on causes between 5 and 25% slowdown in algorithms that access large amounts of memory to, say, exhaustively search a large in-memory data set. I do understand that this is a rare kind of program to be writing, but everything has its place. Sometimes exceptions really don't matter for performance -- for example if you are doing a lot of system calls. None the less, I really wish they hadn't been added to the language. Other people are getting to force their annoyances on me as a developer, and they don't don't even have to write good documentation explaining the exceptions. This could also be true with error codes -- but they are a lot easier to debug than exceptions given the limitations of the tools available to me. We'll just have to agree to disagree. Peace, Lowell
-
Christian Graus wrote:
You reckon ? If your app doesn't handle an exception, it blows up. By 'clients', I mean the people who use your code, not the end user.
And what happens when they wrap your code with a do nothing catch block?
Well, idiot coders are something you can never deal with. But, those people can just ignore a status code, they have to actively suppress an exception.
Christian Graus - Microsoft MVP - C++ "I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
-
A stack trace in the catch block (using VC++ 2003) does not show you where the throw point, it only shows you where the catch currently is -- that is to say the caller of the function that catch occurs in. Perhaps I am just ignorant of how to find the throw point in VC++ 2003, please enlighten me if you know -- I will be forever grateful. (truthfully!)
Well I use C# and VS 2005, but that shouldn't matter. I caught an Exception and viewed the StackTrace and TargetSite values in the Watch window and both showed the method that threw the Exception. Now I think I'll write up a little sample program...
-
Well I use C# and VS 2005, but that shouldn't matter. I caught an Exception and viewed the StackTrace and TargetSite values in the Watch window and both showed the method that threw the Exception. Now I think I'll write up a little sample program...
Hopefully, you'll find a way to help me see the info that I'm not currently able to see. However, in the catch handler, it is the stack trace of the throw point that matters, not the stack trace of the catch block itself. Further, what you'd really like to have is to be able to put a breakpoint in the catch handler and have the debugger understand the throw point and show you the variables in the stack frame of the throw point. Obviously, you can cause the debugger to stop when the throw occurs, but in VC++ 2003, you are not able to filter out throws that you are not interested in. For example, the CFile class throws exceptions for lots of silly reasons. If tell the debugger to stop on all throws, I'm constantly hitting throws which must be ignored -- and I don't know of any way to tell the debugger not to stop at at a particular throw point. If you know of a way to do that, please let me know.
-
Well I use C# and VS 2005, but that shouldn't matter. I caught an Exception and viewed the StackTrace and TargetSite values in the Watch window and both showed the method that threw the Exception. Now I think I'll write up a little sample program...
Here's a simple example. An Exception could be thrown (or passed along) by any of the methods, all will be caught and displayed by the Main.
namespace Template
{
public partial class Template
{
private static int
Div
(
string Op1
,
string Op2
)
{
return ( Div ( int.Parse ( Op1 ) , int.Parse ( Op2 ) ) ) ;
}private static int Div ( int Op1 , int Op2 ) { return ( Op1 / Op2 ) ; } \[System.STAThreadAttribute\] public static int Main ( string\[\] args ) { int result = 0 ; try { System.Console.WriteLine ( Div ( args \[ 0 \] , args \[ 1 \] ) ) ; } catch ( System.Exception err ) { System.Console.WriteLine ( err.Message ) ; System.Console.WriteLine ( err.TargetSite ) ; System.Console.WriteLine ( err.StackTrace ) ; } return ( result ) ; } }
}
In this run Main encounters an error.
C:\>StackTest
Index was outside the bounds of the array.
Int32 Main(System.String[])
at Template.Template.Main(String[] args)In this run the Exception came from deep in the belly of .net
C:\>StackTest a b
Input string was not in a correct format.
Void StringToNumber(System.String, System.Globalization.NumberStyles, NumberBuffer ByRef, System.Globalization.NumberFormatInfo, Boolean)
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.Int32.Parse(String s)
at Template.Template.Div(String Op1, String Op2)
at Template.Template.Main(String[] args)In this run the integer divide threw the Exception
C:\>StackTest 1 0
Attempted to divide by zero.
Int32 Div(Int32, Int32)
at Template.Template.Div(Int32 Op1, Int32 Op2)
at Template.Template.Div(String Op1, String Op2)
at Template.Template.Main(String[] args) -
Hopefully, you'll find a way to help me see the info that I'm not currently able to see. However, in the catch handler, it is the stack trace of the throw point that matters, not the stack trace of the catch block itself. Further, what you'd really like to have is to be able to put a breakpoint in the catch handler and have the debugger understand the throw point and show you the variables in the stack frame of the throw point. Obviously, you can cause the debugger to stop when the throw occurs, but in VC++ 2003, you are not able to filter out throws that you are not interested in. For example, the CFile class throws exceptions for lots of silly reasons. If tell the debugger to stop on all throws, I'm constantly hitting throws which must be ignored -- and I don't know of any way to tell the debugger not to stop at at a particular throw point. If you know of a way to do that, please let me know.
The contents of the trace will depend on whether or not it's a debug build. But I assume that you're debugging a debug build.
-
The contents of the trace will depend on whether or not it's a debug build. But I assume that you're debugging a debug build.
Yep, debug builds for sure.
-
Here's a simple example. An Exception could be thrown (or passed along) by any of the methods, all will be caught and displayed by the Main.
namespace Template
{
public partial class Template
{
private static int
Div
(
string Op1
,
string Op2
)
{
return ( Div ( int.Parse ( Op1 ) , int.Parse ( Op2 ) ) ) ;
}private static int Div ( int Op1 , int Op2 ) { return ( Op1 / Op2 ) ; } \[System.STAThreadAttribute\] public static int Main ( string\[\] args ) { int result = 0 ; try { System.Console.WriteLine ( Div ( args \[ 0 \] , args \[ 1 \] ) ) ; } catch ( System.Exception err ) { System.Console.WriteLine ( err.Message ) ; System.Console.WriteLine ( err.TargetSite ) ; System.Console.WriteLine ( err.StackTrace ) ; } return ( result ) ; } }
}
In this run Main encounters an error.
C:\>StackTest
Index was outside the bounds of the array.
Int32 Main(System.String[])
at Template.Template.Main(String[] args)In this run the Exception came from deep in the belly of .net
C:\>StackTest a b
Input string was not in a correct format.
Void StringToNumber(System.String, System.Globalization.NumberStyles, NumberBuffer ByRef, System.Globalization.NumberFormatInfo, Boolean)
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.Int32.Parse(String s)
at Template.Template.Div(String Op1, String Op2)
at Template.Template.Main(String[] args)In this run the integer divide threw the Exception
C:\>StackTest 1 0
Attempted to divide by zero.
Int32 Div(Int32, Int32)
at Template.Template.Div(Int32 Op1, Int32 Op2)
at Template.Template.Div(String Op1, String Op2)
at Template.Template.Main(String[] args)Yeah - that would be nice. I wonder if there is a way to get VC++ 2003 to dump the processing of the thrown exception so that by the time we get to the breakpoint on the in the catch handler, we can at least see the trace back to the throw point. I'll see if there is something I'm missing in output window from the debugger -- but I've looked before and couldn't find it. Of course, my wife says I couldn't find my nose on my face. I'll spend a little more time checking. Wish me luck.
-
Yeah - that would be nice. I wonder if there is a way to get VC++ 2003 to dump the processing of the thrown exception so that by the time we get to the breakpoint on the in the catch handler, we can at least see the trace back to the throw point. I'll see if there is something I'm missing in output window from the debugger -- but I've looked before and couldn't find it. Of course, my wife says I couldn't find my nose on my face. I'll spend a little more time checking. Wish me luck.
(I think I know where you'd like to find your nose.) Ahem, ahem... so anyway... If it's Managed C++ you should be fine (I guess) as it's a .net issue, not a language issue. In .net at least, when the Exception is instantiated it's populated with the stacktrace at that point. But it does appear that in a standard release build, the stack trace is not fully populated.
-
I agree completely that there is no magic solution. As for my comments about exceptions slowing things down, I have measured it myself with several compilers. Merely compiling with exceptions turned on causes between 5 and 25% slowdown in algorithms that access large amounts of memory to, say, exhaustively search a large in-memory data set. I do understand that this is a rare kind of program to be writing, but everything has its place. Sometimes exceptions really don't matter for performance -- for example if you are doing a lot of system calls. None the less, I really wish they hadn't been added to the language. Other people are getting to force their annoyances on me as a developer, and they don't don't even have to write good documentation explaining the exceptions. This could also be true with error codes -- but they are a lot easier to debug than exceptions given the limitations of the tools available to me. We'll just have to agree to disagree. Peace, Lowell
Hi: Error codes are obsolete and they must be elimated from new software develoment. Error code are ignored and all methods that invoque function with error codes must return error codes, this sucks !! Exception must be cached on BR and loged if you want. Thanks
La entrada es gratis, la salida vemos....
-
I agree completely that there is no magic solution. As for my comments about exceptions slowing things down, I have measured it myself with several compilers. Merely compiling with exceptions turned on causes between 5 and 25% slowdown in algorithms that access large amounts of memory to, say, exhaustively search a large in-memory data set. I do understand that this is a rare kind of program to be writing, but everything has its place. Sometimes exceptions really don't matter for performance -- for example if you are doing a lot of system calls. None the less, I really wish they hadn't been added to the language. Other people are getting to force their annoyances on me as a developer, and they don't don't even have to write good documentation explaining the exceptions. This could also be true with error codes -- but they are a lot easier to debug than exceptions given the limitations of the tools available to me. We'll just have to agree to disagree. Peace, Lowell
Lowell Boggs wrote:
causes between 5 and 25% slowdown
Then you should investigate what the problem is, there's no reason your code should be throwing that many Exceptions.
-
Lowell Boggs wrote:
causes between 5 and 25% slowdown
Then you should investigate what the problem is, there's no reason your code should be throwing that many Exceptions.
The point Lowell is trying to make is that simply compiling with exceptions enabled in C++ causes a 5% to 25% performance hit due to the overhead in function calls, stack manipulation and the inability for the compiler to optimize as well as it can without exceptions enabled. Even if not a single exception was thrown in the entire application, the compiler still has to allow for the possibility that one could be, and this makes it's job much harder and results in a loss of optimizations. Personally I think exceptions have their place, sometimes things beyond our knowledge or control occur, eg a memory access violation where the immediate calling code has no idea about what it should do to handle this kind of error or if the operation that failed is important enough to be fatal to the application. If it's just logging a trace log then who cares? If it's writing a bank account transfer then it's a big deal. This exceptional situation needs to be handled at a higher level where the intention of the code is apparent. I don't think undocumented exceptions should be thrown out of libraries though. Libraries should have a strict interface and exceptions should be well documented for all error conditions.
-
Lowell Boggs wrote:
causes between 5 and 25% slowdown
Then you should investigate what the problem is, there's no reason your code should be throwing that many Exceptions.
The code was not throwing ANY exceptions. The slowdown comes from using the C++ compiler options that enabled exceptions. In the microsoft VC++ compiler, exceptions are disabled by default and you have to use an option to turn them on. However, the point is mute at this point in time -- in order to use the STL on many compilers, you have to compile with exception support. Still, you want a function to be as fast as can be it should be declare in such a way that it does not support exceptions. This may not apply to interpretive languages which are fundamentally slower than compiled languages anyway.