Re: Using performSelector: on super
Re: Using performSelector: on super
- Subject: Re: Using performSelector: on super
- From: Wade Tregaskis <email@hidden>
- Date: Wed, 06 Aug 2008 00:57:04 -0700
The try/catch setup is well optimized and introduces very little
overhead. So in the nominal case, where there is no exception,
there's almost no overhead at all. Even if an exception was
thrown, NSException is fairly lightweight.
This is not particularly accurate.
There, I'll beg to differ.
Exception handlers are cheap ("zero-cost") to set up in C++ and in
the
64-bit Objective-C runtime. They are unfortunately kind of expensive
to set up in 32-bit Objective-C. They are based on setjmp/longjmp.
setjmp/longjmp is very fast. Or at least it used to. I understand
that setjmp has slowed down over the years as more and more state
information needs to be saved to make it work. During my career I've
implemented setjmp/longjmp a few times and it used to take only
about a dozen machine instructions to squirrel away the current
stack pointers into a local structure, return, and perform a
conditional test. Probably faster than objc_msgSend.
I haven't measured it in ages, but I suspect that it's still
reasonably fast. I have several performance intensive applications
that I profile regularly, and my code uses exceptions and try/catch
blocks a lot. I've never seen setjmp or longjmp show up in Shark as
a hot spot. So from casual observation, I'd say that try/catch
blocks don't slow things down too much.
Let me say straight up that I hate exceptions, and code that uses
them. So, I am biased, though I've tried not to be with my
experimentation.
A quick and dirty test program - one which simply throws exceptions as
fast as possible in a fixed-iteration-count loop, measured using the
'time' utility - shows me that the whole exception shebang is about
three or four times more expensive in 64-bit than 32, and that it's at
least three orders of magnitude slower than returning an int. (all on
Intel) I use that as a somewhat relevant counter-example given the
traditional argument between error codes and exceptions as prevailing
models, and given that the original case was using
instancesRespondToSelector:, which while notably more complex
ultimately boils down to returning a scalar, rather than creating an
entire object as with exceptions. [[ admittedly I'm not considering
additional messaging overhead ]]
And I quickly discovered the gotcha that since NSExceptions are
autoreleased, if you happen to be triggering lots of them in a loop
without explicit pool flushes, you'll unnecessarily enlarge your
memory footprint.
I'm not presenting numbers since these tests are so primitive, and I
don't want to go into unnecessary details; the point is well enough
made. If anyone wants to do a full analysis with appropriate controls
and timing and some Shark profiles, be my guest, by all means.
The prevailing wisdom has always been that exceptions are for
exceptional cases. Maybe they would more appropriately titled as
unexpecteds. Intentionally using them as the foundation for
determining whether some class supports some optional or unofficial
interface, or anything of that nature, is a gross abuse of them. And
while, granted, you can happily throw thousands, perhaps tens of
thousands of exceptions a second without a meaningful performance
impact for most programs, it seems simply a bad and unnecessary habit
to get into.
The comment that actually riled me enough to jump in on this thread
was the ever-popular "premature optimisation" card being played. This
card is almost always misplayed in discussions like this. Premature
optimisation is making a design or implementation choice, on the basis
of performance, without sufficient facts. It does not apply
universally as a wildcard whenever you wish to override someone else's
approach - arbitrary or not - with your own. In this case, it is well
demonstrated and well documented that exceptions are expensive.
Relying on them for normal control flow is a bad idea, and against
common wisdom.
It does not need to be proven that it will definitely impact the final
performance; there is a choice in this case between two functional
equivalents for which once is clearly more appropriate and less likely
to become an actual performance issue. This is not premature
optimisation, it is simply mindful design.
Wade
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden