Michael Ash wrote:
Note that dispatch is not mandatory in ObjC either. It is possible
(you get little help from the compiler, but it's not hard) to use
either a vtable approach or a straight function call for method
invocation, as long as you don't mind the loss in functionality that
this implies.

Hi Michael,
If you prefer that route, that is your choice. Given the choice, I would (personally) rather avoid caching selectors and debugging/ maintaining a program that used that behaviour when a well tested alternatives are built into another language's model. Regarding the model, I would not want to reinvent the messaging within my sources. Typical objc class design significantly reduces an optimizer's abilities to do its job.

I must object to this on two points.

First of all, the speed difference is only in messaging and in object
allocation (ObjC not having stack objects means more reliance on the
heap allocator). There is absolutely nothing else to it. If you are
finding differences in speeds for similar operations it's almost
certainly because of differences in the implementations of the
libraries. For example, you'll find that std::string blows the pants
off NSString. It's not because NSString is hobbled by Objective-C,
it's because NSString is vastly more complex and capable. As another
example, a std::vector<int> will blow the pants off an NSMutableArray
of NSNumber. Nothing to do with messaging (or allocation), and
everything to do with the fact that the C++ version is working with
primitives while the ObjC version is not.
This is not actually the case. Foundation -> CoreFoundation types were one significant category of changes. In the aforementioned rewrites, Foundation types were replaced with CoreFoundation types as opposed to std types. Specifically, this _does_ mean that autorelease overhead was reduced in the process, though I consider that a part of the language that cannot be avoided (in using Apple's implementation/ libraries) and thus valid to include in the differences. I never tried to hide that fact when I said "when converting class families/ libraries to C++ for standard application code". GC was not used, figures came from optimized builds. In fact, the stl was rarely used. There *is* more to it, and much of that difference takes place during compilation.

Second, I disagree that C/C++ will be slower only in exceptional
circumstances. Each language has its strengths and weaknesses, and
ObjC's strength is having a wicked fast general dispatcher.
(Considering the decisions going on behind the scenes to figure out
what to invoke, the ~12 CPU cycles spent on each dispatch is a
ridiculously small number.) If your problem happens to map to dispatch
well, then ObjC will be faster for you.

Now, I'm certainly not going to argue that you want to involve ObjC
dispatch in intensive numerical code or anything of the sort. C or C++
clearly win there.
So we are in agreement on that. When I was speaking of 'exceptional circumstances', I was speaking of performance critical code (i.e. numerical) specifically.
But at the same time, I believe that a lot of the problems in a
typical GUI application map better to "dispatch" than to anything
provided in C or C++. I'm sure you're familiar with Greenspun's Tenth
Rule which states, "Any sufficiently complicated C or Fortran program
contains an ad hoc, informally-specified, bug-ridden, slow
implementation of half of Common Lisp." Well I'd like to propose a
parallel rule: "Any sufficiently complicated C or C++ GUI application
contains an ad-hoc, informally-specified, bug-ridden, slow
implementation of a more generalized OO dispatcher."
Amusing. Not always true, but frighteningly common.
Note that I don't mean to criticize C or C++ over this.
I wouldn't mind if you were. Optimization and understanding their targeted runtime is a topic that I believe programmers overlook too frequently, or simply don't care to understand because they can use any of numerous cliches to excuse themselves from writing optimal code. I have put in enough time in both environments to have a _pretty_ good idea of which I would use to implement a class based on the object's intended requirements/duty.

It's simply that they're not good at it, which is fine, they're not supposed to be.
I'd say: Not good at it as a general byproduct of implementation or poor design choices and careless maintenance/evolution, but not specifically due to the underlying runtime/dispatcher. In other words, the improper implementation of some form of an 'intermediate' dispatcher within the libraries used. We already know that C++ dispatch is faster than Objective C (correct?).

But GUI apps tend to need a lot of dispatch, and at ~12 cycles each, it's a bargain in ObjC.
Considering the dynamism of on objc object, 12 cycles is short. Unfortunately, optimization possibilities are reduced, often significantly. There *is* more to this than dispatch, and that really is a portion of the equation that cannot be overlooked. Hopefully I am not coming across as saying C++ is ideal in every program, each language/runtime has its own strengths and weaknesses - it's really the programmer's job to determine which is the right tool to use for their program (and be able to justify their choice). There are too many variables/runtime restrictions that Objective C classes cannot use when an optimization pass occurs that have a significant impact on performance.

When I've seen C/C++ code try to
replicate this kind of decision-making, it tends to involve a lot of C
strings, tons of linear searches, binary searches, or maybe a nice
hash table, and you're lucky to get within a couple orders of
magnitude of objc_msgSend.
Returning to my stance that they (C/C++/Objective-C) are very different tools with different mechanisms, and inherent pros and cons. Again, I would rather leave this task to Apple (in the case of implementing the ObjC runtime/dispatch), who have invested more energy into it than I ever could.

I've written a lot of performance-critical code over the years, both
in ObjC and in other languages, and I have never once found
objc_msgSend to be a critical path in anything. Certainly it *can* be
with a sufficiently perverse or specialized design, but it's rare.
It's not even that a good programmer will avoid it when he gets down
to a certain level, but rather the opposite: you really have to *work*
at using enough messages to make their impact significant.

And one final note, I want to reinforce the fact that this discussion
is 100% unrelated to the original post, which claimed not only that
ObjC was "slow" but that it was slow to the point that a single ObjC
message was glitching his video playback, a statement which simply
does not have any basis in reality no matter how slow the language
might actually be for your purposes.

Mike

Respectfully, there is clearly more than dispatch involved. I would agree that this is unrelated to the original post. It *is* (IMO) related to the observation Jens had along the way, that changing the implementation to plain C solved the issue.

Best,

J

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to