Re: ObjC in time-critical parts of the code

2009-01-19 Thread Michael Ash
On Mon, Jan 19, 2009 at 2:49 AM, Ben Trumbull  wrote:
>> Well no, it doesn't. ObjC has functions, by virtue of being a superset
>> of C, but it does not have "member functions". You can write functions
>> that are logically associated with a class, but this is a human
>> construct, not one that the compiler knows about.
>
> Not sure what compiler you're using, but mine can tell the difference:
> #import 
> @interface Foo : NSObject {
> @private id a;
> }
> @end
> static id plainCFunction(Foo* f);
> static id memberCFunction(Foo* f);
> static id plainCFunction(Foo* f) {
> return f->a;
> }
> @implementation Foo
> static id memberCFunction(Foo* f) {
> return f->a;
> }
> @end
>
> /tmp/members/members.m: In function 'plainCFunction':
> /tmp/members/members.m:12: warning: instance variable 'a' is @private; this
> will be a hard error in the future

That's just a slight modification of access permissions due to the
placement of the function definition. It does not make it a "member",
which to me would mean some kind of namespacing, ownership, or at
least some kind of association with the class. Although the access
permissions are somewhat relaxed, the function is still not associated
with your class in any way.

A minor quibble, but I think it's important, as for example there's no
way to get any information about the function using the Objective-C
runtime, and there's no way to even find out whether the function is a
"member" or not besides diving into the .m file and seeing whether
it's inside or outside the @implementation block.

Mike
___

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


Re: ObjC in time-critical parts of the code

2009-01-19 Thread Scott Ribe
> You're not going to do better straight out of the gate,
> certainly not re-writing them in straight-C.

Of course not. I'm not sure anybody has suggested that (long thread,
could've missed it if it happened). But some of us have suggested not being
automatically averse to C++/STL. Those containers are also highly optimized,
and are able to take advantage of static type info to enable optimization
that you simply cannot get with Objective-C objects & containers.

-- 
Scott Ribe
scott_r...@killerbytes.com
http://www.killerbytes.com/
(303) 722-0567 voice


___

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


Re: ObjC in time-critical parts of the code

2009-01-19 Thread Scott Ribe
> but the decision has *nothing* to do with non-virtual
> member functions or other such oft-touted C++ speed improvements

But actually, it does. The fact is that std::lower_bound is a template that
specializes on the types of the iterators, so what you get is different code
generated depending on the iterator types, and in the case where the
iterators are simple pointers, a whole lot of "functions" that wind up
incurring no function calls at all, but reducing to simple pointer
increments and comparisons, inline--all made possible by static typing
information and C++'s ability to exploit that info. (And even in the cases
where the iterators are more complex, such as maps or sets, the functions
are probably only a line or two and also wind up inlined.)

Exactly the kind of thing I was talking about much earlier in the thread.
There's nothing wrong with NSArray, NSSet & NSDictionary--but the library of
data structures & algorithms in C++ is far more extensive.

-- 
Scott Ribe
scott_r...@killerbytes.com
http://www.killerbytes.com/
(303) 722-0567 voice


___

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


Re: ObjC in time-critical parts of the code

2009-01-19 Thread Bill Bumgarner

On Jan 19, 2009, at 4:21 PM, Kyle Sluder wrote:

On Sun, Jan 18, 2009 at 7:10 PM, Bill Bumgarner  wrote:
Simple question:  Is it better to pursue a 20%, or even 50%,  
improvement in
drawing speed by rewriting in C++ or C than, say, preventing the 2,  
3, 4, or
more extra redraws that are happening prior to window flush?
Don't laugh

-- I have seen it happen.  Often.

This just got posted to programming.reddit.com: "My iPhone is not a
Mac Pro": 
http://www.reddit.com/r/programming/comments/7qxuv/my_iphone_is_not_a_mac_pro_speeding_up_iphone/

In it, the author discusses improving the speed of his iPhone app.
Importantly, he starts by improving the data structure in which he
stores the app's data, and then improving the algorithms used to
access that data.  Eventually he employs some C++ to get a significant
speed boost, but the decision has *nothing* to do with non-virtual
member functions or other such oft-touted C++ speed improvements -- in
fact, he compares it to using -[NSArray
sortedArrayUsingFunction:context:], which doesn't incur the ObjC
dispatch overhead.  It's all about the algorithm, and C++ happened to
have one he could use that improved his code's speed.


Which, of course, would be an utterly pointless optimization if it  
were merely to make the extra-3-unnecessary-redraws fast enough to  
boost his framerate to something acceptable (which was the point of  
the part of my post that you excerpted :).


Fortunately, it sounds like the author of the original article  
actually figured out that they had eked out ever last bit of  
performance from the APIs and, thus, pursued a hybrid solution  
leveraging C++.


Nice article.

b.bum


___

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


Re: ObjC in time-critical parts of the code

2009-01-19 Thread Kyle Sluder
On Sun, Jan 18, 2009 at 7:10 PM, Bill Bumgarner  wrote:
> Simple question:  Is it better to pursue a 20%, or even 50%, improvement in
> drawing speed by rewriting in C++ or C than, say, preventing the 2, 3, 4, or
> more extra redraws that are happening prior to window flush?   Don't laugh
> -- I have seen it happen.  Often.

This just got posted to programming.reddit.com: "My iPhone is not a
Mac Pro": 
http://www.reddit.com/r/programming/comments/7qxuv/my_iphone_is_not_a_mac_pro_speeding_up_iphone/

In it, the author discusses improving the speed of his iPhone app.
Importantly, he starts by improving the data structure in which he
stores the app's data, and then improving the algorithms used to
access that data.  Eventually he employs some C++ to get a significant
speed boost, but the decision has *nothing* to do with non-virtual
member functions or other such oft-touted C++ speed improvements -- in
fact, he compares it to using -[NSArray
sortedArrayUsingFunction:context:], which doesn't incur the ObjC
dispatch overhead.  It's all about the algorithm, and C++ happened to
have one he could use that improved his code's speed.

--Kyle Sluder
___

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


Re: ObjC in time-critical parts of the code

2009-01-19 Thread William Jon Shipley
Simple question:  Is it better to pursue a 20%, or even 50%,  
improvement in drawing speed by rewriting in C++ or C than, say,  
preventing the 2, 3, 4, or more extra redraws that are happening  
prior to window flush?   Don't laugh -- I have seen it happen.  Often.


I subscribed to this list just to agree with Bill, here. Every good  
developer I know has found a speed-up in completely adopting Objective- 
C and Cocoa, NOT a slowdown. Of COURSE you can write bad code in  
Objective-C. But it encourages you not to.


In my experience, MOST programs out there suffer from performance  
problems that are caused by large-scale inefficiencies, NOT small- 
scale inefficiencies:


For example, a large-scale inefficiency would be a database interface  
where you malloc() and copy the data six times before the user sees  
it, instead of just retaining it and passing around the same pointer.  
(This was really the case with the original DBKit (predecessor to EOF,  
predecessor to CoreData), except I think it was more than 6, it was,  
like, 15.) Method calls are nothing compared to memory allocation, yet  
people spend most of their time freaking out about the overhead of a  
method, and none thinking, "Damn, it's nice to have a coherent  
strategy for handling memory."


Using Cocoa means those kinds of problems are avoided from the start.

On the other hand, a small-scale inefficiency would be, like, a tight  
loop where you run through a buffer and increment each byte by two.  
And honestly (a) compilers are good at optimizing this kind of thing,  
(b) it's really not very common, and (c) processors are super-fast  
anyhow. And usually the best answer is to go higher-level with these  
problems, anyways (eg, use vecLib).


--

Think about the kinds of problems that are slow. What do they involve?  
Usually, large data sets. I mean, if you're doing only one operation,  
it's REALLY hard to make that slow, nowadays.


Apple's spent a TON of time optimizing their collection classes.  
NSArray, NSSet, NSDictionary -- they are all on their, like, fifth  
iteration. You're not going to do better straight out of the gate,  
certainly not re-writing them in straight-C.


--

I will go this far: I would never hire anyone who complains seriously  
about Objective-C being slow, because what you have there is someone  
who hasn't written a complete system. She's a theoretical programmer,  
not a real one. "In THEORY, straight C should be faster." Yes, if  
*you* were a perfect programmer, and could rewrite very complex  
systems from scratch in a low-level language without introducing any  
bugs on inefficiencies... but the last 50 years of computer  
programming have proven that there are maybe four or five programmers  
in the world like this. (John Carmack, for instance.)


-Wil
___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Ben Trumbull
On Sun, Jan 18, 2009 at 9:23 PM, Ben Trumbull   
wrote:
Several work arounds exist.  The easiest is to create a static C  
member
function (yes, ObjC has member *functions* which most people  
overlook).


Well no, it doesn't. ObjC has functions, by virtue of being a superset
of C, but it does not have "member functions". You can write functions
that are logically associated with a class, but this is a human
construct, not one that the compiler knows about.


Not sure what compiler you're using, but mine can tell the difference:

#import 

@interface Foo : NSObject {
@private id a;
}
@end

static id plainCFunction(Foo* f);
static id memberCFunction(Foo* f);

static id plainCFunction(Foo* f) {
return f->a;
}

@implementation Foo
static id memberCFunction(Foo* f) {
return f->a;
}
@end


/tmp/members/members.m: In function 'plainCFunction':
/tmp/members/members.m:12: warning: instance variable 'a' is @private;  
this will be a hard error in the future


- Ben

___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Justin Carlson


From: Chris Williams 

> In 25 years in the computer business, I've seen precisely one  
example of
> someone successfully re-coding around performance issues with the  
language

> or library.  And that was only because they coded a tiny snippet of
> assembler that managed to fit into the pre-fetch cache of an 80286.

Amazing. I have been more fortunate (?)

> Every other time, the effort would've been far better spent  
avoiding unnecessary
> calls and work in their own design than wasting time fighting or  
rewriting

> the language/library.

I emphasize good design from the start, which perhaps sets a different  
type of standard. It is slower to write (as if line count were a good  
thing), but it pays off in the end because programs are easier to  
maintain, last longer, and are more reusable. I've seen such important  
changes mny times. Outperforming system libraries really isn't  
difficult, and it *can* make a difference in performance critical code.


The people writing system libraries/frameworks are also programmers -  
the algorithm they chose may not be the best for a particualr app. easy.


Hardware changes, uses for computers change. Surely, in 25 years there  
must have been at least one example of (or in) a library that was not  
initially delivered with an OS that you have benefited from? (Even if  
it was included with the OS in source, binary, or concept at a later  
date).


Again, this is performance critical code - I have 0 idea what your  
projects involved, but I know optimization can be learned. First  
indicator: There are people who can read a source file and suggest  
meaningful changes, and there are those who cannot. This trait is  
fundamental to be able to write performance critical code - and there  
are many details beyond that.


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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Michael Ash
On Sun, Jan 18, 2009 at 9:23 PM, Ben Trumbull  wrote:
> Several work arounds exist.  The easiest is to create a static C member
> function (yes, ObjC has member *functions* which most people overlook).

Well no, it doesn't. ObjC has functions, by virtue of being a superset
of C, but it does not have "member functions". You can write functions
that are logically associated with a class, but this is a human
construct, not one that the compiler knows about. It's a useful
technique to be sure, but it's important to realize that from the
language point of view these are just standard C functions, nothing
more.

Mike
___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Justin Carlson


Ben Trumbull,

Thank you for sharing your experiences on the subject in extent!

Regards,

Justin


___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Chris Williams
In 25 years in the computer business, I've seen precisely one example of
someone successfully re-coding around performance issues with the language
or library.  And that was only because they coded a tiny snippet of
assembler that managed to fit into the pre-fetch cache of an 80286.  Every
other time, the effort would've been far better spent avoiding unnecessary
calls and work in their own design than wasting time fighting or rewriting
the language/library.

> From: Justin Carlson 
> 
> Optimization is learned, and it takes time to learn.

___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Justin Carlson


On Jan 18, 2009, at 8:23 PM, Bill Bumgarner wrote:


On Jan 18, 2009, at 6:05 PM, Justin Carlson wrote:

I have also seen (unspecified) system libraries worsen considerably  
over time - 'faster over the course of OS releases' is not as sunny  
as I once believed. Believing system libraries will get faster is  
dangerous.


You have filed bugs against said regressions?  Performance  
regressions are serious business.   Send me the bug #s offlist.  I  
would like to track them.


Not all of them, though some of the bigger ones were reported and/or  
mentioned along the way. I'd rather not spend time digging up old  
bugs. Some have been fixed, some have not. Oh well, there is always  
the next release.


Spending loads of engineering time re-inventing the wheel is folly.   
It often isn't faster, is generally buggier, and consumes a ton of  
time that could be better used actually shipping something.


H... that's a generalization. It's true that it can be time  
consuming, but it's really not tough to outdo a program by isolating  
the behaviour you need. Who's to say one person's implementation of  
what is provided by a system library function is better than yours -  
for the problem at hand? If it is time critical, it is really not  
uncommon for a good optimizer to make a specific implementation which  
outperforms a generic system implementation - several times over.


Not to be meant as an insult to anyone's engineering skills on this  
list.  Simply that if you were to focus as much time on optimizing  
and debugging an algorithm found in a system library as the  
engineers who wrote and now maintain said library, you are unlikely  
going to have enough time left over to ship your product.


b.bum


Optimization is learned, and it takes time to learn.

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Justin Carlson

On Jan 18, 2009, at 7:36 PM, Greg Titus wrote:



On Jan 18, 2009, at 5:13 PM, Justin Carlson wrote:



Jean-Daniel Dupas wrote:
>
> Each time you use KVC/KVO.

Hi Jean-Daniel,

Sorry if I misreading this, your response was short - it could mean  
a few things. I am inclined to think you were responding to my  
question "how often do your subclasses rewrite getters/setters?".



Justin,

Jean-Daniel was referring to the way that Apple has implemented  
automatic KVO compatibility. The first time that someone tries to  
observe an object of class X with accessor -foo, and -setFoo:, the  
framework makes a dynamic subclass of your class X called something  
like X_KVO, and reimplements -setFoo: to be something like:


- (void)setFoo:(id)aFoo
{
[self willChangeValueForKey:@"foo"];
[super setFoo:aFoo];
[self didChangeValueForKey:@"foo"];
}

It then replaces the original X class with the X_KVO class (using a  
mechanism like -poseAs:) so that all existing X's are now X_KVO's.  
This automatic and dynamic subclassability of getters/setters makes  
KVO a lot easier to use, because a lot of it happens for you without  
any effort on the programmer's part. And, of course, this wouldn't  
be possible had the setter been defined non-virtually in a language  
like C++. So here's an example of the dynamism being useful for even  
the smallest and simplest of methods (that would normally be inlined  
in a C++ framework design).


Hope this helps,
- Greg



Hi Greg,

Thank you for clarifying Jean-Daniel's response. ObjC has nice  
features, strengths, and conveniences; neither I nor Scott tried to  
make that argument against ObjC. Unfortunately, this mechanism does  
not compare to the alternatives in performance critical zones - where  
the 'free' interface is usually overkill for member access. I'm not  
saying that it is not a necessary ingredient to the mechanics of KVC/ 
KVO, just that there are better alternatives in performance critical  
zones.


Regards,

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Justin Carlson


On Jan 18, 2009, at 7:20 PM, mmalc Crawford wrote:

On Jan 18, 2009, at 5:13 PM, Justin Carlson wrote:


I would generally write:
- (void)setMovie:(MyMovie *)newMovie {
// make sure it is ok here

In general your accessors should not perform validation; instead you  
should implement the appropriate KVV-conformant method.





mmalc


Hi mmalc,

Sorry - Bad example. My example would typically be a high level  
operation, unless it applied to one of the few programs that happens  
to deal with mny instances of MyMovie.


In the context of ObjC in time critical code: Your point does bring  
the additional overhead of KVC to the discussion.


Regards,

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Bill Bumgarner

On Jan 18, 2009, at 6:05 PM, Justin Carlson wrote:

I have also seen (unspecified) system libraries worsen considerably  
over time - 'faster over the course of OS releases' is not as sunny  
as I once believed. Believing system libraries will get faster is  
dangerous.


You have filed bugs against said regressions?  Performance regressions  
are serious business.   Send me the bug #s offlist.  I would like to  
track them.


Spending loads of engineering time re-inventing the wheel is folly.   
It often isn't faster, is generally buggier, and consumes a ton of  
time that could be better used actually shipping something.


Not to be meant as an insult to anyone's engineering skills on this  
list.  Simply that if you were to focus as much time on optimizing and  
debugging an algorithm found in a system library as the engineers who  
wrote and now maintain said library, you are unlikely going to have  
enough time left over to ship your product.


b.bum




___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Ben Trumbull
wine, wine, wine.  My inline asm blocks look the same regardless of  
which language I use.


Seriously, though, peek at /usr/include/objc/runtime.h and Behold that  
ObjC is ...  uhm, well, C with a custom front end and some nice  
structs a library maintains for me.  Okay, really very nice library.   
I try not to laugh at people who tell me they can't use ObjC because  
it's too slow and they're going to use C instead.


More constructively, I've noticed a few things in performance tuning  
over the years.  Fundamentally, these are in style and idioms derived  
from what the syntax encourages.  As such, some of these micro- 
optimizations do accumulate to become frictionally systemic as part of  
common patterns.  I don't use C++ anymore, but credit where credit is  
due.


(1) polymorphism, or not.  The default C++ method is monomorphic, and  
just a function.  You need to tag it 'virtual' to get link time  
binding.  ObjC methods default to runtime binding.  It'd be awesome to  
get earlier binding in ObjC.


Several work arounds exist.  The easiest is to create a static C  
member function (yes, ObjC has member *functions* which most people  
overlook).  The public method can just call the static function, and  
if it's in the same compilation unit, the compiler will inline it.   
Optimized code that doesn't mind losing polymorphism can just call the  
function directly.  ObjC member functions + custom CF callbacks = mega- 
nifty.  Alas, toll free bridging of the Foundation classes with custom  
CF callbacks is not supported.  Member functions don't have to be  
static, so they can be performance SPI as well.  And for the times  
when it's important to send the very best, a non-static member  
function can call the inlined static version just like the method,  
having a single factored implementation with 3 different performance  
characteristics.


I've suggested tagging methods to be private to the link unit (app,  
framework, etc) since typically one wants to be able to inline  
accessor method invocations across compilation units.  Which leads  
to ...


(2) inlining.  There really isn't any disputing that C++ is friendlier  
to compile time optimizations like inlining and code movement.  It  
does so by avoiding features that enable technologies like KVC & KVO.   
Template metaprogramming is in many ways focused toward shifting  
optimization complexity onto the compiler.  And who wouldn't want to  
outsource, for free, hard work onto those very smart folks ?  Many  
simple C++ methods are declared in header files.  ObjC doesn't have a  
good definition of a monomorphic method, so people who need to opt  
into that have to jump through hoops.


For example, there's no way to declare an inline member function in a  
ObjC header file.  Back to #define.


(3) object allocation.  C++ is much friendlier to temporary objects  
including idioms for stack objects.  Since most objects are ephemeral,  
avoiding heap churn entirely is handy.  Less locking, less  
fragmentation, way faster.  Also easy to screw up. It's possible to  
use stack objects in ObjC, with CFAllocator, but there's no syntax or  
idiomatic support, so it's extremely dangerous.  Personally, I'd love  
to see syntax, perhaps like DO annotations, for stating that an object  
you pass out or receive is only valid for that stack's scope.


C++ also prefers = operator overloading to enhance retain counting  
instead of -autorelease.  This leads to the compiler maintaining the  
scope of the temp object's lifetime instead of the programmer guessing  
(invariably badly, as code evolves) where to put NSAutoreleasePool.   
No extra memory to implement the NSAutoreleasePool, no extraneous  
extension of object lifetimes, no unnecessary increase in heap high  
watermark.  Compiler does a way better job.  And a number of very  
interesting idioms have developed around the construction and  
destruction of stack objects, such that C++ effectively allows  
delegate hooks at each lexical scope.


(4) autorelease Jihad!  Jihad!  It averages about 13x slower due to  
additional memory pressure and heap fragmentation.  It's also, imo,  
impossible to correctly maintain NSAutoreleasePools as code evolves.   
Especially with other people's libraries and frameworks (e.g. my loop  
was fine, and then in version 10.++ you leaked an object into my  
autorelease pool and shafted me.  Not bitter).  Controlling &  
debugging the performance characteristics of code built around  
autorelease has just been a waste of my time.  Now, I only use  
autorelease when (a) coerced or (b) it's the lesser evil compared to a  
@try block.


(5) exceptions.  The idioms for both languages have been shaped by  
their error handling styles.  This also impacts how to ref count  
expensive resources and delegates at lexical boundaries.  Finally, on  
the 64 bit runtime, we have modern exceptions.  Modern exceptions are  
very expensive to actually throw, in both languages, howeve

Re: ObjC in time-critical parts of the code

2009-01-18 Thread Justin Carlson


>I've been watching this discussion w/great interest.  Thanks.
>
> 	A lot of the discussion seems to be focused on micro-optimizations  
and little focused on systemic optimizations.

>
> 	One point that I have yet to see mentioned is the overall  
performance enhancements to be had by focusing on embracing the high  
level services of the system.

>
> 	And by overall performance enhancement, I specifically mean that  
it lets you ship a working product in less time. And by "working  
product", I mean "product that performs well enough to keep customers  
happy".

>
> 	As well, by focusing on achieving maximal integration of your code  
into the subsystems of the system, you can often gain a tremendous  
amount of efficiency.

>
> 	Simple question: Is it better to pursue a 20%, or even 50%,  
improvement in drawing speed by rewriting in C++ or C than, say,  
preventing the 2, 3, 4, or more extra redraws that are happening prior  
to window flush? Don't laugh -- I have seen it happen. Often.

>
> 	As well, there are areas of optimization for which Apple has  
entire teams dedicated to squeezing every last ounce of performance  
out of every variant of CPU and/or GPU shipped.

>
> 	As an added benefit, doing so means that your code is much more  
likely to just get faster across major releases of Mac OS X (and a  
handful of minor releases, too).

>
>b.bum
>

Hi Bill,

Like all developers, I don't have the time (or desire) to implement  
every aspect of a program. Implementation is of course inevitable, and  
reinventing the wheel is frequently a poor use of time. For me, it  
really comes down to what you're responsible for implementing. I try  
to make my written code good before anyone else can use it. And yes,  
using the system's APIs does have its benefits - a great selling point  
for me when I chose to use Cocoa. If you find that the performance is  
poor following implementation, then a programmer should be inclined to  
understand why. If there is only enough time to implement some of  
that, begin with the easiest changes  
which_are_in_line_with_the_ideal_solution - Don't apply a handful of  
mud to an existing program as a patch. Apple has invested much energy  
into performance, which I'm thankful for. I have also seen  
(unspecified) system libraries worsen considerably over time - 'faster  
over the course of OS releases' is not as sunny as I once believed.  
Believing system libraries will get faster is dangerous. Strangely,  
another good reason to have solid code from the day it is written.  
Thanks for mentioning bringing in these points.


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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Greg Titus


On Jan 18, 2009, at 5:13 PM, Justin Carlson wrote:



Jean-Daniel Dupas wrote:
>
> Each time you use KVC/KVO.

Hi Jean-Daniel,

Sorry if I misreading this, your response was short - it could mean  
a few things. I am inclined to think you were responding to my  
question "how often do your subclasses rewrite getters/setters?".



Justin,

Jean-Daniel was referring to the way that Apple has implemented  
automatic KVO compatibility. The first time that someone tries to  
observe an object of class X with accessor -foo, and -setFoo:, the  
framework makes a dynamic subclass of your class X called something  
like X_KVO, and reimplements -setFoo: to be something like:


- (void)setFoo:(id)aFoo
{
[self willChangeValueForKey:@"foo"];
[super setFoo:aFoo];
[self didChangeValueForKey:@"foo"];
}

It then replaces the original X class with the X_KVO class (using a  
mechanism like -poseAs:) so that all existing X's are now X_KVO's.  
This automatic and dynamic subclassability of getters/setters makes  
KVO a lot easier to use, because a lot of it happens for you without  
any effort on the programmer's part. And, of course, this wouldn't be  
possible had the setter been defined non-virtually in a language like C 
++. So here's an example of the dynamism being useful for even the  
smallest and simplest of methods (that would normally be inlined in a C 
++ framework design).


Hope this helps,
- Greg

___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread mmalc Crawford


On Jan 18, 2009, at 5:13 PM, Justin Carlson wrote:


I would generally write:
- (void)setMovie:(MyMovie *)newMovie {
// make sure it is ok here

In general your accessors should not perform validation; instead you  
should implement the appropriate KVV-conformant method.





mmalc

___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Justin Carlson


Jean-Daniel Dupas wrote:

> > An additional problem is that it does not scale well. Programs  
mature,
> > objects are used beyond their initial intent, programmers come  
and go
> > and that source becomes a nightmare to maintain. Getting back to  
good
> > OO style, why take the messaging overhead (how often do your  
subclasses

> > rewrite getters/setters?)
>
> Each time you use KVC/KVO.

Hi Jean-Daniel,

Sorry if I misreading this, your response was short - it could mean a  
few things. I am inclined to think you were responding to my question  
"how often do your subclasses rewrite getters/setters?".


The point that I was trying to make was that accessors are _generally_  
not implemented by the subclass, but by the class which declares them  
(at least, as I write them).


I would generally write:

- (void)setMovie:(MyMovie *)newMovie {
// make sure it is ok here
	// actually change the instance variable here (do retain/release  
dance, etc.)
	// If by interface, call a designated update method which subclasses  
may implement, such as [self movieChanged]. You could also use use KVO  
for this.

}

- (MyMovie *)movie {
// make sure it is ok here
	// actually return the instance variable (do retain/autorelease dance  
if applicable, etc.)

}

This allows the accessors to be straightforward (a good thing,  
considering the amount of redundance), and subclasses could then  
implement [MyMoviePlayer movieChanged] for their custom interpretation  
of the object's implementation. Of course, there is no need to signal  
(i.e. call movieChanged) for every ivar, or to provide a unique call  
for every ivar. Back to the point that I was trying to make: Some  
people generally put their objects' *real* implementation in the  
accessors, but that is not generally a good design (again, IMO) since  
it is difficult to maintain complex class hierarchies - even if you  
call super's implementation through the class which declared the ivar.  
In most cases, it is easiest to maintain classes with minimal  
accessors, which signal a change (where applicable), rather than 3  
subclasses later, implementing the accessor. It keeps code small and  
focused. In C++, that would be rephrased as: "How often do your  
accessors need to be virtual?".


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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread mmalc Crawford


On Jan 18, 2009, at 4:10 PM, Bill Bumgarner wrote:

One point that I have yet to see mentioned is the overall  
performance enhancements to be had by focusing on embracing the high  
level services of the system.
And by overall performance enhancement, I specifically mean that it  
lets you ship a working product in less time.  And by "working  
product", I mean "product that performs well enough to keep  
customers happy".


As a sort of tangent to this, I've for a long time said that the  
slowest-running application is the one you haven't shipped yet...


mmalc

___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Dave DeLong
All this reminds me a quote I found in an old PC Week:

"Objective-C is the result of adding object facilities to C with the goal of 
making programmers more productive. The result differs greatly from C++, which 
adds objects to C without making computers less efficient: quite a different 
goal."   [PC Week, November 3, 1997] 

I think bbum hit it on the head. We can get some seriously awesome 
optimizations out of C++, but the purpose of this languages is ultimately quite 
different from the purpose of Objective-C (as I see it).  C++, from what I 
understand, is meant to be a computer efficient OO language, whereas 
Objective-C was designed to be a "programmer efficient" OO language.

Dave

On Sunday, January 18, 2009, at 05:19PM, "Michael Ash"  
wrote:
>On Sun, Jan 18, 2009 at 7:10 PM, Bill Bumgarner  wrote:
>> I've been watching this discussion w/great interest.  Thanks.
>>
>> A lot of the discussion seems to be focused on micro-optimizations and
>> little focused on systemic optimizations.
>>
>> One point that I have yet to see mentioned is the overall performance
>> enhancements to be had by focusing on embracing the high level services of
>> the system.
>>
>> And by overall performance enhancement, I specifically mean that it lets you
>> ship a working product in less time.  And by "working product", I mean
>> "product that performs well enough to keep customers happy".
>
>THANK YOU for saying this. I know that you will be attacked for saying
>this, just watch. People will say that this philosophy does not apply
>on laptops, or on iPhones, or whatever. Efficiency is always king,
>they'll say! But you're 100% right about this. "Optimization" should
>not refer to code efficiency, it should refer to *product* efficiency.
>
>Engineers treat "optimization" as a holistic process which involves
>balancing money, time, reliability, and other factors as well as
>straight-up product performance. Software engineering is no exception
>to the necessity of this, but somehow the education in this area seems
>to be completely absent. Certainly I never learned about the tradeoffs
>involved in product management when I was in school, and I don't think
>very many people do, but it's key to making a good product.
___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Justin Carlson


Quincey Morris wrote:

> TBH (and more to the point) I strongly suspect it's true of  
everyone who's

> expressed an opinion in this thread that it's not so much about the
> suitability of the language to optimizations, but more about the  
skill

> set of the individual with regard to the language.

In my case, I have been using Objective C extensively for over 5  
years. I don't use it everywhere I *could* (other messages provide  
explanation), but I do believe I understand it well enough back up my  
statements and observations. I *would* say I am better with nontrivial  
C++ designs -- a portion of that is undeniably attributed to the  
additional control and power provided by a more extensive language. I  
knew enough at the time to take every suggestion that has been made  
into consideration. Having said that, I don't believe this supports  
your suspicion.


Justin

___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Michael Ash
On Sun, Jan 18, 2009 at 7:10 PM, Bill Bumgarner  wrote:
> I've been watching this discussion w/great interest.  Thanks.
>
> A lot of the discussion seems to be focused on micro-optimizations and
> little focused on systemic optimizations.
>
> One point that I have yet to see mentioned is the overall performance
> enhancements to be had by focusing on embracing the high level services of
> the system.
>
> And by overall performance enhancement, I specifically mean that it lets you
> ship a working product in less time.  And by "working product", I mean
> "product that performs well enough to keep customers happy".

THANK YOU for saying this. I know that you will be attacked for saying
this, just watch. People will say that this philosophy does not apply
on laptops, or on iPhones, or whatever. Efficiency is always king,
they'll say! But you're 100% right about this. "Optimization" should
not refer to code efficiency, it should refer to *product* efficiency.

Engineers treat "optimization" as a holistic process which involves
balancing money, time, reliability, and other factors as well as
straight-up product performance. Software engineering is no exception
to the necessity of this, but somehow the education in this area seems
to be completely absent. Certainly I never learned about the tradeoffs
involved in product management when I was in school, and I don't think
very many people do, but it's key to making a good product.

Mike
___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Bill Bumgarner

I've been watching this discussion w/great interest.  Thanks.

A lot of the discussion seems to be focused on micro-optimizations and  
little focused on systemic optimizations.


One point that I have yet to see mentioned is the overall performance  
enhancements to be had by focusing on embracing the high level  
services of the system.


And by overall performance enhancement, I specifically mean that it  
lets you ship a working product in less time.  And by "working  
product", I mean "product that performs well enough to keep customers  
happy".


As well, by focusing on achieving maximal integration of your code  
into the subsystems of the system, you can often gain a tremendous  
amount of efficiency.


Simple question:  Is it better to pursue a 20%, or even 50%,  
improvement in drawing speed by rewriting in C++ or C than, say,  
preventing the 2, 3, 4, or more extra redraws that are happening prior  
to window flush?   Don't laugh -- I have seen it happen.  Often.


As well, there are areas of optimization for which Apple has entire  
teams dedicated to squeezing every last ounce of performance out of  
every variant of CPU and/or GPU shipped.


As an added benefit, doing so means that your code is much more likely  
to just get faster across major releases of Mac OS X (and a handful of  
minor releases, too).


b.bum


___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Jean-Daniel Dupas


Le 19 janv. 09 à 00:56, Justin Carlson a écrit :


John Engelhart wrote:

> On Sat, Jan 17, 2009 at 7:44 PM, Scott Ribe  wrote:
> >> TBH (and more to the point) I strongly suspect it's true of  
everyone
> >> who's expressed an opinion in this thread that it's not so much  
about
> >> the suitability of the language to optimizations, but more  
about the

> >> skill set of the individual with regard to the language.
> >
> > Well, there is a degree of efficiency that can be had with C++  
classes that

> > simply cannot be had with Objective-C classes.
>
> You keep mentioning this, but I don't recall seeing an example of  
this

> 'inefficiency' you keep referring to.  If I were to take a guess at
> it, I'd venture that it's along the lines of "accessing a variable  
of

> a struct/class", or something along the lines of:

That is one good example, but there is *much* more to it.

> Of course, that's just one way to do it.  The ObjC language doesn't
> require that you write getters and setters to access an instances
> ivars, that's just good OO programming style.  But since you're
> talking about "optimized performance" code then I think "knowing  
when

> to bend the rules" is perfectly fair game, as long as you understand
> the consequences.  The ObjC example above can then be rewritten as:
> [code]
> This translates exactly in to the same instructions as the "pure,  
raw

> C" version.  You obviously loose the flexibility of the ObjC OO
> getter/setter way, but you're in control of that trade-off.  This  
is a

> completely acceptable "bending of the rules" when doing performance
> optimization and the need for performance outweighs the loss of
> functionality or extra complexity elsewhere to compensate for the
> performance special case.

An additional problem is that it does not scale well. Programs  
mature, objects are used beyond their initial intent, programmers  
come and go and that source becomes a nightmare to maintain. Getting  
back to good OO style, why take the messaging overhead (how often do  
your subclasses rewrite getters/setters?)


Each time you use KVC/KVO.

___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Justin Carlson

John Engelhart wrote:

> On Sat, Jan 17, 2009 at 7:44 PM, Scott Ribe  wrote:
> >> TBH (and more to the point) I strongly suspect it's true of  
everyone
> >> who's expressed an opinion in this thread that it's not so much  
about
> >> the suitability of the language to optimizations, but more about  
the

> >> skill set of the individual with regard to the language.
> >
> > Well, there is a degree of efficiency that can be had with C++  
classes that

> > simply cannot be had with Objective-C classes.
>
> You keep mentioning this, but I don't recall seeing an example of  
this

> 'inefficiency' you keep referring to.  If I were to take a guess at
> it, I'd venture that it's along the lines of "accessing a variable of
> a struct/class", or something along the lines of:

That is one good example, but there is *much* more to it.

> Of course, that's just one way to do it.  The ObjC language doesn't
> require that you write getters and setters to access an instances
> ivars, that's just good OO programming style.  But since you're
> talking about "optimized performance" code then I think "knowing when
> to bend the rules" is perfectly fair game, as long as you understand
> the consequences.  The ObjC example above can then be rewritten as:
> [code]
> This translates exactly in to the same instructions as the "pure, raw
> C" version.  You obviously loose the flexibility of the ObjC OO
> getter/setter way, but you're in control of that trade-off.  This  
is a

> completely acceptable "bending of the rules" when doing performance
> optimization and the need for performance outweighs the loss of
> functionality or extra complexity elsewhere to compensate for the
> performance special case.

An additional problem is that it does not scale well. Programs mature,  
objects are used beyond their initial intent, programmers come and go  
and that source becomes a nightmare to maintain. Getting back to good  
OO style, why take the messaging overhead (how often do your  
subclasses rewrite getters/setters?), the poor style, or the program  
that is extremely difficult to maintain -- when you generally won't  
need any of that?


Why deny free optimizations (provided by the compiler) and risk poor  
design/maintenance headaches?


> If you decided to use
> getter and setter methods to access a classes ivars, that was a  
design

> choice on your part, not a requirement imposed by the language.

But who *wants* to maintain code with inconsistent ivar accessing?  
That misses the point and power of oo design, as well as the  
simplicity of it (where applicable). Default visibility was decided,  
for good reason.


> As a consequence of this, your statements that "ObjC is far less
> efficient than C" are rather specious. The only reasonable way I can
> think of that would lead you to this conclusion is that you're not
> comparing apples to apples, i.e. you're using struct->var type
> accesses in C, and getter/setter runtime dispatched methods in ObjC.
> That's not a fair comparison, nor the way any sane person would  
code a
> "performance optimized" version.  (very?) Selective use of direct  
ivar

> access and imp caching map to the equivalent of struct->member +
> function calls in C, which effectively means that if you're not
> getting the same (or very close to) performance from your "ObjC
> performance benchmarks" as you are from the C version, you're doing
> something wrong.
>
> (note: Most of the above applies to the 32-bit runtime.  I'm not
> looking to start a 32/64-bit runtime religious war.)

Nor is it fair to assume that somebody would want to make their  
program more complex to maintain than necessary by doing so,  
especially when these are often gratis in another language. It's all  
coming back to the right tool for the job at hand. I don't mean to  
sound like I believe one language is superior, they each have their  
strengths (and weaknesses). Objective C is great (depending on how it  
is used). C++ is great (depending on how it is used).


Justin



___

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


Re: ObjC in time-critical parts of the code

2009-01-18 Thread Justin Carlson

Michael Ash wrote:

> > 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.
>
> I agree that it's ugly, but it's good to have the option.

Agreed.

> My preferred approach is to use plain ObjC without such ugly  
optimizations, and

> then add in such optimizations later if they become necessary. So far
> they have almost never been necessary. Where they have been  
necessary,

> I've found them to be quite clean, at least from my perspective as a
> long-time C programmer. Here's one example of using dynamic-sized
> public ivars to store per-thread per-object data structures instead  
of

> storing everything in a dictionary:
>
> http://www.mikeash.com/svn/ChemicalBurn/ChemicalBurnNode.h
>
> This is a bit ugly but IMO not terribly so, and the speed gain was
> impressive. The point here is that there's no reason to be afraid  
that

> using ObjC will get you stuck in some performance hole that you can't
> dig out of without a rewrite. Just like any other language, do good
> high-level design and otherwise write the simplest thing that will
> work, then come back later and make the hotspots faster.

And my stance is that these languages (or dialects) interoperate well.  
Each dialect has positives and negatives as part of the standard  
language and written conventions.


I'd take this saying and expand on it:
Just like any other language, do good high-level design. Emphasize  
reuse, genericity, simplicity, expected behaviour, make designs small  
and minimal (optimal) from the beginning, expect that they will be  
used beyond your immediate needs. Understand what you are writing, and  
choose the best tool for the program/task.


Programs written to this model tend not to need as many optimizations  
or precarious/time consuming changes after the fact.


When I write 'Understand what you are writing, and choose the best  
tool for the program/task.', this means that a programmer needs to  
know the environment and how their program will be compiled and the  
consequences that their choices make. This doesn't imply 'dream in  
assembly', but it does imply that making the wrong choices carries  
consequences which tend to outweigh the time investment on the front  
end. Therefore, choosing ObjC over C++ (or any other combination)  
during an object's inception is imperative to good design. Knowing the  
difference is one distinction between a good programmer and a not-so- 
good programmer. Otherwise, it is too easy to get stuck in a trap  
where you're doing extensive rewriting -- assuming one cares enough to  
do more about it than cite Moore's Law. If you scroll back a few  
messages, you'll see that I have been through this multiple times, and  
it includes code that I have written. So I'd say a programmer *should*  
be afraid of design decisions and implementations which they do not  
fully understand, that she/he should attempt to understand in order to  
make a decision. Your synopsis does not get into enough detail to  
specify strongly one way or the other, so don't take this as I am  
calling you out on this matter. One could interpret what you've  
written (the last bit) as 'lazy programming, until it becomes a  
problem', which is unfortunately too common these days.


ObjC and C++ are different enough that there are right and wrong  
choices when designing, these choices can considerably affect how a  
program runs (as I've mentioned). Assuming you have both languages  
available; Making all objects C++ classes or all objcts ObjC classes  
in a _real_ (or complex) program is a significant design flaw (IMO).



> I would place autorelease in with "object allocation", which I  
already

> mentioned. Autoreleasing an object just somewhat increases its
> allocation costs. There's the question of memory pressure, but if you
> encounter that, it's easily dealt with by adding inner autorelease
> pools, so it's not inevitable.
>
> I'd be really surprised if you turned up a speed difference between
> otherwise identical code using NSString and CFString or other
> toll-free-bridged Foundation/CF classes. They use the same
> implementation underneath, after all, so the only difference is
> messaging and autorelease, neither of which are going to be
> significant compared to the real work going on underneath in most
> cases.

These were not functional rewrites (in the sense of a user's  
perspective), but restructuring and informed optimzations. Consider it  
Refactoring -- on a very large scale (multiple projects which incurred  
100s of 1000s of  source lines changed).  This tells me that you're  
skeptical and don't know the differences yourself since you have never  
tried, *or* that I am terrifyingly wrong in my observations among  
multiple extensive works. On one side there are assumptions and little  
motivation to understand(1) -- when provided with enou

Re: ObjC in time-critical parts of the code

2009-01-18 Thread Scott Ribe
Good grief, no. I'm not just talking about accessors. Try re-reading:

> In addition, in many cases where Objective-C would have one or more method
> dispatches in innermost performance-critical regions, with C++/STL you will
> have NO FUNCTION CALL AT ALL, but rather direct pointer-based data access or
> inlined code. In my own testing, I've found that to be the biggest difference,
> because Objective-C method dispatch is in fact pretty efficient method
> dispatch.

Objective-C severely limits the degree of inlining that can be accomplished
when using classes and method calls. C++ allows (promotes, really) a heavy
degree of inlining.

> I'm not sure you appreciate the irony of having "people who don't
> really understand Objective-C" and "but in Objective-C would require
> raw C" in the same sentence.

There is no irony at all. Of course Objective-C is just C plus an efficient
dispatcher & some easy syntax. Of course you can rewrite in raw C. The point
was, in C++, you can get the same performance as the raw C, but without
using raw C, while still using the higher-level objects & method calls
(which in some cases will even be far less verbose than Objective-C.)

> As a consequence of this, your statements that "ObjC is far less
> efficient than C" are rather specious.

I never said any such thing. Please do not set up straw man arguments to
knock me down--I *will* call you on it, *every* single time.

> The only reasonable way I can
> think of that would lead you to this conclusion is that you're not
> comparing apples to apples, i.e. you're using struct->var type
> accesses in C, and getter/setter runtime dispatched methods in ObjC.

You clearly have no idea about the optimization possibilities of C++ class
templates.

In essence, the stricter/static typing of C++ allows many more optimizations
to be applied to object-oriented code (not just plain C), and the more
dynamic typing of Objective-C restricts the possibilities (while enabling
techniques that are particularly nice for UI work).

-- 
Scott Ribe
scott_r...@killerbytes.com
http://www.killerbytes.com/
(303) 722-0567 voice


___

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


Re: ObjC in time-critical parts of the code

2009-01-17 Thread John Engelhart
On Sat, Jan 17, 2009 at 7:44 PM, Scott Ribe  wrote:
>> TBH (and more to the point) I strongly suspect it's true of everyone
>> who's expressed an opinion in this thread that it's not so much about
>> the suitability of the language to optimizations, but more about the
>> skill set of the individual with regard to the language.
>
> Well, there is a degree of efficiency that can be had with C++ classes that
> simply cannot be had with Objective-C classes.

You keep mentioning this, but I don't recall seeing an example of this
'inefficiency' you keep referring to.  If I were to take a guess at
it, I'd venture that it's along the lines of "accessing a variable of
a struct/class", or something along the lines of:

// C version
struct Example { int x, y; };
struct Example *ep;
int localX = ep->x;
ep->x = 1234;

// ObjC version
@interface Example { int x, y; }
- (int)x;
- (int)y;
- (void)setX:(int)newX;
- (void)setY:(int)newY;
@end

Example *eo;
int localX = [eo x];
[eo setX:1234];

In this particular example, the ObjC version is "less efficient" than
the "raw C" version.  Each access to the 'x' class ivar has to take a
trip through the runtime message dispatcher.  The C version translates
in to assembly that is really nothing more than loading/storing with a
pointer + the offset to the desired struct member (1-3 instructions,
give or take), which obviously and easily trumps the time it takes the
ObjC dynamic runtime version.

Of course, that's just one way to do it.  The ObjC language doesn't
require that you write getters and setters to access an instances
ivars, that's just good OO programming style.  But since you're
talking about "optimized performance" code then I think "knowing when
to bend the rules" is perfectly fair game, as long as you understand
the consequences.  The ObjC example above can then be rewritten as:

@interface Example { @public int x, y; }
- (int)x;
- (int)y;
- (void)setX:(int)newX;
- (void)setY:(int)newY;
@end

Example *eo;
int localX = eo->x;
eo->x = 1234;

This translates exactly in to the same instructions as the "pure, raw
C" version.  You obviously loose the flexibility of the ObjC OO
getter/setter way, but you're in control of that trade-off.  This is a
completely acceptable "bending of the rules" when doing performance
optimization and the need for performance outweighs the loss of
functionality or extra complexity elsewhere to compensate for the
performance special case.

> It is a degree of efficiency
> that is not often required, but just as you can't "rewrite Cocoa in C++" as
> we've seen demanded by people who don't really understand Objective-C,
> there's levels of efficiency that in C++ can be combined with high-level
> abstractions, but in Objective-C would require raw C.

I'm not sure you appreciate the irony of having "people who don't
really understand Objective-C" and "but in Objective-C would require
raw C" in the same sentence. After all, Objective-C is nothing but
syntactic sugar for C- any ObjC statement can be rewritten in its
(usually far more verbose) C equivalent.  When you get right down to
it, the core difference between C and Objective-C is the message
dispatcher, and its use is completely optional.  If you decided to use
getter and setter methods to access a classes ivars, that was a design
choice on your part, not a requirement imposed by the language.

As a consequence of this, your statements that "ObjC is far less
efficient than C" are rather specious. The only reasonable way I can
think of that would lead you to this conclusion is that you're not
comparing apples to apples, i.e. you're using struct->var type
accesses in C, and getter/setter runtime dispatched methods in ObjC.
That's not a fair comparison, nor the way any sane person would code a
"performance optimized" version.  (very?) Selective use of direct ivar
access and imp caching map to the equivalent of struct->member +
function calls in C, which effectively means that if you're not
getting the same (or very close to) performance from your "ObjC
performance benchmarks" as you are from the C version, you're doing
something wrong.

(note: Most of the above applies to the 32-bit runtime.  I'm not
looking to start a 32/64-bit runtime religious war.)
___

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


Re: ObjC in time-critical parts of the code

2009-01-17 Thread Scott Ribe
> Yikes! I hope you realize that for some of us of a certain computing
> era, this statement looks quite strange. As if you said, perhaps, that
> you were prone to reducing your fuel consumption by going back to
> driving a Hummer.

Yes, I realize that. Particularly for those who are only familiar with "old
style" C++.

> TBH (and more to the point) I strongly suspect it's true of everyone
> who's expressed an opinion in this thread that it's not so much about
> the suitability of the language to optimizations, but more about the
> skill set of the individual with regard to the language.

Well, there is a degree of efficiency that can be had with C++ classes that
simply cannot be had with Objective-C classes. It is a degree of efficiency
that is not often required, but just as you can't "rewrite Cocoa in C++" as
we've seen demanded by people who don't really understand Objective-C,
there's levels of efficiency that in C++ can be combined with high-level
abstractions, but in Objective-C would require raw C.

-- 
Scott Ribe
scott_r...@killerbytes.com
http://www.killerbytes.com/
(303) 722-0567 voice


___

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


Re: ObjC in time-critical parts of the code

2009-01-17 Thread Quincey Morris

On Jan 17, 2009, at 15:49, Scott Ribe wrote:


it's just that I'm more prone than many to optimize by throwing
in some strategic C++


Yikes! I hope you realize that for some of us of a certain computing  
era, this statement looks quite strange. As if you said, perhaps, that  
you were prone to reducing your fuel consumption by going back to  
driving a Hummer.


TBH (and more to the point) I strongly suspect it's true of everyone  
who's expressed an opinion in this thread that it's not so much about  
the suitability of the language to optimizations, but more about the  
skill set of the individual with regard to the language.



___

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


Re: ObjC in time-critical parts of the code

2009-01-17 Thread Scott Ribe
> The point here is that there's no reason to be afraid that
> using ObjC will get you stuck in some performance hole that you can't
> dig out of without a rewrite.

Just to be clear re my earlier posts: I completely agree with that
assessment; it's just that I'm more prone than many to optimize by throwing
in some strategic C++. (Also agree that Objective-C is nice for UI work.)

 
-- 
Scott Ribe
scott_r...@killerbytes.com
http://www.killerbytes.com/
(303) 722-0567 voice


___

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


Re: ObjC in time-critical parts of the code

2009-01-17 Thread Michael Ash
On Sat, Jan 17, 2009 at 2:02 AM, Justin Carlson
 wrote:
>
> 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 agree that it's ugly, but it's good to have the option. My preferred
approach is to use plain ObjC without such ugly optimizations, and
then add in such optimizations later if they become necessary. So far
they have almost never been necessary. Where they have been necessary,
I've found them to be quite clean, at least from my perspective as a
long-time C programmer. Here's one example of using dynamic-sized
public ivars to store per-thread per-object data structures instead of
storing everything in a dictionary:

http://www.mikeash.com/svn/ChemicalBurn/ChemicalBurnNode.h

This is a bit ugly but IMO not terribly so, and the speed gain was
impressive. The point here is that there's no reason to be afraid that
using ObjC will get you stuck in some performance hole that you can't
dig out of without a rewrite. Just like any other language, do good
high-level design and otherwise write the simplest thing that will
work, then come back later and make the hotspots faster.

>> 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 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.

I would place autorelease in with "object allocation", which I already
mentioned. Autoreleasing an object just somewhat increases its
allocation costs. There's the question of memory pressure, but if you
encounter that, it's easily dealt with by adding inner autorelease
pools, so it's not inevitable.

I'd be really surprised if you turned up a speed difference between
otherwise identical code using NSString and CFString or other
toll-free-bridged Foundation/CF classes. They use the same
implementation underneath, after all, so the only difference is
messaging and autorelease, neither of which are going to be
significant compared to the real work going on underneath in most
cases.

>> 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.

Not sure how numerical code gets a monopoly on performance cri

Re: ObjC in time-critical parts of the code

2009-01-17 Thread Scott Ribe
> Furthermore, vtables are not mandatory in all cases/calls. A
> good optimizer (or properly written class) can overcome such
> dependencies in several cases - optimization is far easier to
> accomplish outside the constraints of the ObjC runtime. So you get
> faster messaging, and more optimization control from C++ objects.

In addition, in many cases where Objective-C would have one or more method
dispatches in innermost performance-critical regions, with C++/STL you will
have NO FUNCTION CALL AT ALL, but rather direct pointer-based data access or
inlined code. In my own testing, I've found that to be the biggest
difference, because Objective-C method dispatch is in fact pretty efficient
method dispatch.

-- 
Scott Ribe
scott_r...@killerbytes.com
http://www.killerbytes.com/
(303) 722-0567 voice


___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Justin Carlson


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 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 d

Re: ObjC in time-critical parts of the code

2009-01-16 Thread Michael Ash
On Fri, Jan 16, 2009 at 8:03 PM, Justin Carlson
 wrote:
> Of course. Benchmarks were provided, which only cover a portion of the
> subject. Furthermore, vtables are not mandatory in all cases/calls. A good
> optimizer (or properly written class) can overcome such dependencies in
> several cases - optimization is far easier to accomplish outside the
> constraints of the ObjC runtime. So you get faster messaging, and more
> optimization control from C++ objects.

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.

> The point I am making is: If you know you're working with performance
> critical code, C interfaces or C++ objects/messaging will be slower only in
> exceptional cases (assuming well written objects wrt the language/messaging
> in use), objc objects will only complicate opportunities for optimization
> (from several perspectives). Don't get me wrong, objc a great oo language,
> but writing a standard oo interface with it will either make your
> (performance critical) program either comparably very slow or comparably
> slow and unnecessarily messy/bloated/complex - In short, it is the wrong
> tool for the job. That is my experience and my opinion. So my suggestion is
> that performance critical objects should avoid the objc interface/language
> from the start. I have invested much time in this, and proven it in multiple
> real world cases (not small projects, but complex real programs that
> required much time to change), and provided average real world results in my
> previous messages. I believe everyone involved agrees/knows that the speed
> difference is more than messaging.

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 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.

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.

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."

Note that I don't mean to criticize C or C++ over this. It's simply
that they're not good at it, which is fine, they're not supposed to
be. But GUI apps tend to need a lot of dispatch, and at ~12 cycles
each, it's a bargain in ObjC. 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.

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 Ob

re: ObjC in time-critical parts of the code

2009-01-16 Thread Justin Carlson

Note no one that responded to Jens is stating that the Objective-C way
of doing message dispatching cannot cause performance critical
pathways to be "hotter" then desired compared to direct function
calls, C++ vtable dispatching, etc. The point has been that just don't
assume that is the source of a problem. Properly analyze what is going
on and then make adjustments.


Hi Shawn,

Of course. Benchmarks were provided, which only cover a portion of the  
subject. Furthermore, vtables are not mandatory in all cases/calls. A  
good optimizer (or properly written class) can overcome such  
dependencies in several cases - optimization is far easier to  
accomplish outside the constraints of the ObjC runtime. So you get  
faster messaging, and more optimization control from C++ objects.


Also what Jens posted for the timings of message sends was WAY off  
from the reality.


Ok. The test (and likely the cited benchmarks) are also unlike  
standard program behaviour, though that was not the point I was making.



Anyway note using things like IMP caching in performance problem areas
will gain you speeds often better then you would via C++ vtable
dispatch. So you don't have to drop the use Objective-C because of
message send over head (in most real world situations).

-Shawn


Again, virtual calls are not always necessary components of  
performance critical zones. That argument misdirects the point I was  
making; that argument assumes C++ operates more closely to an objc  
object than usual. I know about IMP caching, and other workarounds,  
and yes, I did evaluate these options when doing the tests and ports I  
cited in my response. For me, IMP caching, @defs punning and all other  
such workarounds only served to complicate the program, and such  
changes were outperformed in my tests/programs by properly written C++  
objects.


The point I am making is: If you know you're working with performance  
critical code, C interfaces or C++ objects/messaging will be slower  
only in exceptional cases (assuming well written objects wrt the  
language/messaging in use), objc objects will only complicate  
opportunities for optimization (from several perspectives). Don't get  
me wrong, objc a great oo language, but writing a standard oo  
interface with it will either make your (performance critical) program  
either comparably very slow or comparably slow and unnecessarily messy/ 
bloated/complex - In short, it is the wrong tool for the job. That is  
my experience and my opinion. So my suggestion is that performance  
critical objects should avoid the objc interface/language from the  
start. I have invested much time in this, and proven it in multiple  
real world cases (not small projects, but complex real programs that  
required much time to change), and provided average real world results  
in my previous messages. I believe everyone involved agrees/knows that  
the speed difference is more than messaging.


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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Jens Bauer

Hi Shawn,

Thankyou for the detailed explanation.
I've probably been too quick to jump to the conclusion, and even  
though it works better (I've still seen no chops), I agree that  
something else most likely have an impact on my application.



On Jan 16, 2009, at 18:26, Shawn Erickson wrote:

On Fri, Jan 16, 2009 at 8:00 AM, Michael Ash   
wrote:



To repeat: something else is going on.


If I had to guess (an we do since the OP didn't post any actionable
information) the following possibilities come to mind...

1) logic bug in the code he replaced
2) memory management issue in the code he replaced that caused memory
pressure or maybe gc (didn't state if he was using or not)
3) some other application task stalling the event loop now not
affected by the code he replaced (didn't state what was driving the
rendering)
4) rendering tasks ran long enough to bump up against schedular
quantum with other pressure in the system
5) etc.


I'm pretty sure it's not issue #1, since the code is copied, pasted  
and downgraded to C. -It's almost identical. Still I'm not claiming to  
write error-free code.

#2: I'm not using the Garbage Collector.
#3: This might be possible.
#4: I don't think it is; unless it's hidden from me. I've not been  
considering the pmtool - does that run without activity viewer ? -It  
would most likely not be cron, because cron on my machine is running  
max. every 5 minutes, but there might be others. I've disabled  
spotlight indexing (in the Finder)

#5: Also a possibility that could cause it. ;)


[obj-c, shark, Microseconds...]


I'll spend some more time with Shark this weekend, so maybe I'll learn  
things I don't know yet.
I know that Microseconds are inaccurate, but it should be able to  
measure milliseconds.



...as to why we are pushing back on your statements...

I want to make sure others that wander into this thread in the future
don't get mislead and make the wrong decisions. Also we are trying to
push you to understand what your problem truly was (...guess it is now
to late to help you avoid rewriting code, which was my first goal).


Understandable. Maybe my modifications will be helpful later on, though.
I will have to redesign the code, and I will be able to start by  
testing for these differences.

If it helps moving to a new architecture, I will post a follow-up.


p.s. Samples taken on a first generation Mac Pro 2.66GHz but a G5
wouldn't be drastically different to my Mac Pro in message dispatch
speeds.


Thanks. =)


Love,
Jens

___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Shawn Erickson
On Fri, Jan 16, 2009 at 2:26 PM, Justin Carlson
 wrote:
>
> Sorry if I come across as the devil's advocate on this one - I think there
> should be another voice stating that objc use can slow a program.

Note no one that responded to Jens is stating that the Objective-C way
of doing message dispatching cannot cause performance critical
pathways to be "hotter" then desired compared to direct function
calls, C++ vtable dispatching, etc. The point has been that just don't
assume that is the source of a problem. Properly analyze what is going
on and then make adjustments.

Also what Jens posted for the timings of message sends was WAY off
from the reality.

Anyway note using things like IMP caching in performance problem areas
will gain you speeds often better then you would via C++ vtable
dispatch. So you don't have to drop the use Objective-C because of
message send over head (in most real world situations).

-Shawn
___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Justin Carlson


Sorry if I come across as the devil's advocate on this one - I think  
there should be another voice stating that objc use can slow a program.


Compared to C or C++, Objective C is a poor choice for performance  
critical code. Within performance critical zones, I will only use objc  
objects for very high level objects, and even then, rarely. I do use  
objc objects for things such as user interfaces. I've done a few  
ports, even for standard application level programs (omitting  
graphics), the difference is typically several times faster. I've made  
libraries which use C and C++ objects/interfaces, objc programs which  
are modified to use these libraries are noticeably faster. If a  
program needs to be fast, objc cannot compete with C or C++ objects  
(unless the programmer has missed important concepts of oo design or  
for some other unusual reason).


In short, I typically saw changes of 5 - 8 times the speed when  
converting class families/libraries to C++ for standard application  
code. That is just a change of the class' language - no complex  
optimizations there (other than what GCC includes), most programs can  
be optimized well beyond that point. I don't use objc objects for  
performance critical code - and, yes, I have spent much time with  
performance tools on this and other areas. The explanations for these  
differences obviously extend beyond 'how fast can a nop objc method be  
sent 1000 times in a row'? -- I don't need to convince anybody to use  
one approach over the other (it sounds like everybody is already  
convinced, anyhow!), I just thought I'd state that there significant  
gains can be made by simply avoiding objc objects in performance  
critical code (which back up both sides of the argument). I don't  
actually have hours to explain why this is so -- It shouldn't require  
an optimization expert to conclude (or reason) why the difference is  
so large. Besides, if your program needs that kind of speed, the best  
thing you can do is figure out why the difference exists. Other  
bonuses typically include significantly smaller executables and fewer  
exported symbols.


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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Shawn Erickson
On Fri, Jan 16, 2009 at 8:00 AM, Michael Ash  wrote:

> To repeat: something else is going on.

If I had to guess (an we do since the OP didn't post any actionable
information) the following possibilities come to mind...

1) logic bug in the code he replaced
2) memory management issue in the code he replaced that caused memory
pressure or maybe gc (didn't state if he was using or not)
3) some other application task stalling the event loop now not
affected by the code he replaced (didn't state what was driving the
rendering)
4) rendering tasks ran long enough to bump up against schedular
quantum with other pressure in the system
5) etc.

Jens,

Knowing the objective-c dispatch implementation I can say with high
level of certainty you are blaming the wrong thing (it wont can a
delay close to what you reported, a couple orders of magnitude lower
at worst) and your code change corrected or avoided something that you
happened to be doing wrong/inefficiently and/or a bad assumption you
made.

Shark will help you understand hot pathways using time profile or
using a Shark system trace you can understand how you are interacting
with the system including thread context switches. If you use dtrace
and/or Instruments you could actually trigger on every entry and exit
to messages sent to your render object to build up timing information,
etc.

Finally the accuracy of Microsecond is on the order of microseconds or
10s of microseconds (and who knows its exact jitter behavior). Message
sends are on the order of nanoseconds (if a hot message) to 10s of
nanoseconds (if cool). Using something like UpTime can get you down
under a microsecond in accuracy but still easily an order of magnitude
to large still to measure a single message send. You will do nothing
but mislead your self if you try to use something with Microsecond
accuracy to understand something that takes nanoseconds.

(CPU performance counters can get you better but...)

Also the time spent in UpTime or Microseconds is itself on the order
of 10s of nanoseconds which is far longer then a simple message send.

[0:562] > gcc -framework Foundation -framework CoreServices Test.m; ./a.out
...
2009-01-16 09:08:34.647 a.out[42577:10b] average of 1 calls to
Microseconds: 91 ns
2009-01-16 09:08:34.648 a.out[42577:10b] average of 1 calls to UpTime: 46 ns

You really need to sample across a batch of operations and/or record
time stamps at important locations and then average the deltas to
avoid time granularity misleading you. Again it is best to leverage
profiling tools to help track down how you application is spending its
time and/or affecting (or being affected by) the system.

...as to why we are pushing back on your statements...

I want to make sure others that wander into this thread in the future
don't get mislead and make the wrong decisions. Also we are trying to
push you to understand what your problem truly was (...guess it is now
to late to help you avoid rewriting code, which was my first goal).

-Shawn

p.s. Samples taken on a first generation Mac Pro 2.66GHz but a G5
wouldn't be drastically different to my Mac Pro in message dispatch
speeds.
___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Michael Ash
On Fri, Jan 16, 2009 at 3:27 AM, Jens Bauer  wrote:
> Hi Greg,
>
> On Jan 16, 2009, at 08:39, Greg Titus wrote:
>
>> The point of what people are trying to tell you is that the result you are
>> getting (3ms per empty Objective-C call) is approximately 500,000 times
>> longer than the time you ought to be getting (5-6ns). If an Objective-C
>> message send took 3 milliseconds (333 method calls per second!), no useful
>> software could ever have been written in the language.
>
> Just a comment.. It's not every invocation of the empty method that takes
> 3ms, it's just happening often.
> What I'm concerned about, is the peak values, that makes chops in my
> rendering. I thought it was the fault of my rendering code, and it did take
> me some time to figure out that it wasn't *inside* my rendering, but
> *outside* it, that the time was spent.

Preemptive multitasking can make any piece of code spontaneously
appear to take several milliseconds to execute, because it can get
preempted in the middle of running and not come back for quite a
while.

>> From your guess at the end of your post, ("message dispatcher servicing")
>> it is pretty clear that you don't really know what is going on.
>
> :) I don't think any of us (except from Apple) knows what's exactly going on
> in there. ;)

Seriously?

Seriously?!!?!

To repeat what I said before, it's not magic. The Objective-C
dispatcher is nothing special. I, and many other people, have read the
source code to it. I believe that I can safely say that I understand
*exactly* what is going on in the dispatcher. And this is not a boast.
It's not like saying I know *exactly* what is going on inside the
Space Shuttle. More like I know exactly what is going on inside a
flush toilet. It just is not that complex. I'd wager at least half of
the people responding to you understand *exactly* what is going on
inside the Objective-C dispatcher as well.

>> Blaming the language environment for performance behavior that is vastly
>> different than any of the rest of us have ever seen is not likely to be
>> useful to you at all. There is something else happening with your
>> application.
>
> Uhm... Just to be stubborn: I changed the rendering to use plain C-routines,
> and now it doesn't get those high peak values anymore, and the chopping is
> gone.
> Yes, it's still an assumption, that this fixed it. I will try and see if it
> continues to work, but it definitely seems so much better right now.

You saw a problem, you made a change, the problem went away. You have
no idea *what the problem was*, just that your change made it
disappear. Until you actually find out what your program was doing
when it was spending all that time not working, your suppositions and
guesses are not really very useful.

Your supposition simply makes no sense. First, it is in conflict with
what everyone else has seen. Second, it is in conflict with what *you*
see. So you've removed all the Objective-C from your rendering code.
Your app is still Cocoa, right? Well guess what: Cocoa makes an
enormous number of Objective-C calls to do anything. You may have
eliminated all the ObjC calls from your own code, but every single
time you draw a frame to the screen I guarantee you that Cocoa makes
at least hundreds if not thousands of ObjC calls to make that happen.
If the ObjC dispatcher were really the problem, surely removing only
the calls in your own code would not have fixed it.

To repeat: something else is going on.

Mike
___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Jean-Daniel Dupas


Le 16 janv. 09 à 11:19, Jens Bauer a écrit :


Hi Jean-Daniel,

On Jan 16, 2009, at 09:32, Jean-Daniel Dupas wrote:


You don't want to understand.


I'm sorry, if it appears to be like I do not want to understand.  
I've been working all night on this, and I'm quite sleepy right now.
My results after changing to plain C are much better. My conclusion  
is based upon what I can see as results, they may still be wrong.


You CANNOT mesure elapsed time for ONE call. You have to bench  
thousand of call in one loop and take an average time.


Yes and no. It depends on what the purpose is.
To see an average value, you'll have to do just that, however, in my  
case, to discover when/why the chops happen, I did this - initially  
because I thought that my code sometimes was to blame.


You first conclusion IS WRONG and it does not depend if you have 20  
threads or only one. Your PEAK VALUE is WRONG too. It's not  
possible to mesure a peak value, especially in a preemptive  
environment.


You're right about that, and I agree to a certain point.
My rendering is pretty quick (it's using highly optimized code and  
already prepared data).
When the code I have is using a lot of ObjC invocations, it appears  
to me that it's more likely to be hit, than when it doesn't.

-Both in theory, and when I look at the result.
The only way I can explain that it works better with clean C (apart  
from superstitious explanations), is that something that happens in  
the message dispatcher, is not happening anymore.


I've tried debugging into the message-dispatcher, however I failed  
to coninue at some point, which is expected (I've written debuggers  
in the past as well).




I'm using An Obj-C based library to render two 1080p movies into an  
OpenGL context, applying shaders and more.
I'm using the QTKit which are objc classes and a core video display  
link.

The display link callback call an obj-c method to render the each frame.
The rendering method use a dictionary to manage the movie it should  
draw. Each movie use an objc class to managed it's visual context.
The renderer send messages to each movies, that send messages to each  
visual context to find updated frames.

Then it delegate the rendering part to an other class.
The real renderer retreive the new frames using objc methods, it setup  
OpenGL shader wrap into ObjC classes using objc methods.

It enable them using other ObjC method call.
And there is a lot of other messages to setup wrapper OpenGL frame  
buffer, to draw reflection, and more.


That's make a lots of message for each frame rendering and I don't see  
any glitch so, I doubt the problem is in the obj-c runtime.



___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Jens Bauer

Hi Jean-Daniel,

On Jan 16, 2009, at 09:32, Jean-Daniel Dupas wrote:


You don't want to understand.


I'm sorry, if it appears to be like I do not want to understand. I've  
been working all night on this, and I'm quite sleepy right now.
My results after changing to plain C are much better. My conclusion is  
based upon what I can see as results, they may still be wrong.


You CANNOT mesure elapsed time for ONE call. You have to bench  
thousand of call in one loop and take an average time.


Yes and no. It depends on what the purpose is.
To see an average value, you'll have to do just that, however, in my  
case, to discover when/why the chops happen, I did this - initially  
because I thought that my code sometimes was to blame.


You first conclusion IS WRONG and it does not depend if you have 20  
threads or only one. Your PEAK VALUE is WRONG too. It's not possible  
to mesure a peak value, especially in a preemptive environment.


You're right about that, and I agree to a certain point.
My rendering is pretty quick (it's using highly optimized code and  
already prepared data).
When the code I have is using a lot of ObjC invocations, it appears to  
me that it's more likely to be hit, than when it doesn't.

-Both in theory, and when I look at the result.
The only way I can explain that it works better with clean C (apart  
from superstitious explanations), is that something that happens in  
the message dispatcher, is not happening anymore.


I've tried debugging into the message-dispatcher, however I failed to  
coninue at some point, which is expected (I've written debuggers in  
the past as well).



Love,
Jens

___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Sherm Pendley

On Jan 16, 2009, at 3:27 AM, Jens Bauer wrote:

:) I don't think any of us (except from Apple) knows what's exactly  
going on in there. ;)


Um, at least one of the folks you're arguing with (not me) *is* from  
Apple.


sherm--

___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Andrew Farmer

On 16 Jan 09, at 00:27, Jens Bauer wrote:
From your guess at the end of your post, ("message dispatcher  
servicing") it is pretty clear that you don't really know what is  
going on.


:) I don't think any of us (except from Apple) knows what's exactly  
going on in there. ;)


Sure we do!

http://www.opensource.apple.com/darwinsource/10.5.6/objc4-371.2/runtime/
___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Jean-Daniel Dupas


Le 16 janv. 09 à 09:27, Jens Bauer a écrit :


Hi Greg,

On Jan 16, 2009, at 08:39, Greg Titus wrote:

The point of what people are trying to tell you is that the result  
you are getting (3ms per empty Objective-C call) is approximately  
500,000 times longer than the time you ought to be getting (5-6ns).  
If an Objective-C message send took 3 milliseconds (333 method  
calls per second!), no useful software could ever have been written  
in the language.


Just a comment.. It's not every invocation of the empty method that  
takes 3ms, it's just happening often.
What I'm concerned about, is the peak values, that makes chops in my  
rendering. I thought it was the fault of my rendering code, and it  
did take me some time to figure out that it wasn't *inside* my  
rendering, but *outside* it, that the time was spent.


From your guess at the end of your post, ("message dispatcher  
servicing") it is pretty clear that you don't really know what is  
going on.


:) I don't think any of us (except from Apple) knows what's exactly  
going on in there. ;)


The objc runtime is open sourced.


___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Jean-Daniel Dupas


Le 16 janv. 09 à 09:03, Jens Bauer a écrit :


Hi Jeremy,

On Jan 16, 2009, at 04:52, Jeremy Pereira wrote:


On 15 Jan 2009, at 22:16, Jens Bauer wrote:


..often used around 3ms for the empty method "-renderObject".
It gave me the terrible result of up to 21ms spent in the empty  
method!


-So I'd like to let you know that it's sometimes good to think "do  
I really need this method?"
I will be rewriting around 8 of my large files for doing some  
rendering, so they will be using C-routines instead of ObjC  
methods, since I'm using them in a real-time environment.


My guess is that the message dispatcher probably needs to do  
something else than servicing *my* application, so I believe it's  
the nature of the environment, not a bug


I compiled your program into an Xcode project.  I got an answer of  
0.021ms.


I modified the project to call renderObject 1,000 times and I got  
the answer 0.028ms.


The only thing I can think of is that you have confused  
milliseconds and microseconds.


I believe that it depends on if the application is doing something  
else, rather than just an empty loop.
In my case, I have at least one extra thread running, sometimes more  
threads.
The project is running on a G5 DP/2.0GHz, and will not be used on  
intel machines, so many of you might get faster execution times than  
me.
-But the 'warning' isn't about the average value, it's about the  
peak value, which sometimes takes ages, and when doing a real-time  
app, it might be important to avoid such peak values.



You don't want to understand.
You CANNOT mesure elapsed time for ONE call. You have to bench  
thousand of call in one loop and take an average time.
You first conclusion IS WRONG and it does not depend if you have 20  
threads or only one. Your PEAK VALUE is WRONG too. It's not possible  
to mesure a peak value, especially in a preemptive environment.





___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Jens Bauer

Hi Greg,

On Jan 16, 2009, at 08:39, Greg Titus wrote:

The point of what people are trying to tell you is that the result  
you are getting (3ms per empty Objective-C call) is approximately  
500,000 times longer than the time you ought to be getting (5-6ns).  
If an Objective-C message send took 3 milliseconds (333 method calls  
per second!), no useful software could ever have been written in the  
language.


Just a comment.. It's not every invocation of the empty method that  
takes 3ms, it's just happening often.
What I'm concerned about, is the peak values, that makes chops in my  
rendering. I thought it was the fault of my rendering code, and it did  
take me some time to figure out that it wasn't *inside* my rendering,  
but *outside* it, that the time was spent.


From your guess at the end of your post, ("message dispatcher  
servicing") it is pretty clear that you don't really know what is  
going on.


:) I don't think any of us (except from Apple) knows what's exactly  
going on in there. ;)


Blaming the language environment for performance behavior that is  
vastly different than any of the rest of us have ever seen is not  
likely to be useful to you at all. There is something else happening  
with your application.


Uhm... Just to be stubborn: I changed the rendering to use plain C- 
routines, and now it doesn't get those high peak values anymore, and  
the chopping is gone.
Yes, it's still an assumption, that this fixed it. I will try and see  
if it continues to work, but it definitely seems so much better right  
now.


We're just trying to save you the effort of rewriting and then  
discovering that nothing about the timing problem has changed,  
because you have misidentified the problem.


I know. -But I had to get rid of the chopping, and I couldn't find any  
other possibilities than to time my program.

Fortunately, it didn't take as long to rewrite, as I first expected.
I haven't noticed any lags of this kind before, which means that high  
peak impacts are probably not happening in general.
-I just got shocked, when I saw the results. It could be because I'm  
not supposed to use ObjC-code in a CVDisplayLink callback function.




Good luck,


Thanks. :)


Love,
Jens

___

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


Re: ObjC in time-critical parts of the code

2009-01-16 Thread Jens Bauer

Hi Jeremy,

On Jan 16, 2009, at 04:52, Jeremy Pereira wrote:


On 15 Jan 2009, at 22:16, Jens Bauer wrote:


..often used around 3ms for the empty method "-renderObject".
It gave me the terrible result of up to 21ms spent in the empty  
method!


-So I'd like to let you know that it's sometimes good to think "do  
I really need this method?"
I will be rewriting around 8 of my large files for doing some  
rendering, so they will be using C-routines instead of ObjC  
methods, since I'm using them in a real-time environment.


My guess is that the message dispatcher probably needs to do  
something else than servicing *my* application, so I believe it's  
the nature of the environment, not a bug


I compiled your program into an Xcode project.  I got an answer of  
0.021ms.


I modified the project to call renderObject 1,000 times and I got  
the answer 0.028ms.


The only thing I can think of is that you have confused milliseconds  
and microseconds.


I believe that it depends on if the application is doing something  
else, rather than just an empty loop.
In my case, I have at least one extra thread running, sometimes more  
threads.
The project is running on a G5 DP/2.0GHz, and will not be used on  
intel machines, so many of you might get faster execution times than me.
-But the 'warning' isn't about the average value, it's about the peak  
value, which sometimes takes ages, and when doing a real-time app, it  
might be important to avoid such peak values.


I changed the NSLog to report microseconds instead of milliseconds,  
and to avoid sending a million of lines, I recorded the max peak values:


if(renderTime > maxRender)
{
maxRender = renderTime;
NSLog(@"time: %.03fus", renderTime);
}

1/16/09 08:36:53 MyApplication[22784] time: 2552.000us
1/16/09 08:37:33 MyApplication[22784] time: 3467.000us
1/16/09 08:38:34 MyApplication[22784] time: 3705.000us
1/16/09 08:40:36 MyApplication[22784] time: 3872.000us
1/16/09 08:46:41 MyApplication[22784] time: 6753.000us
1/16/09 08:53:20 MyApplication[22784] time: 7985.000us

When I use only C-routines, I get no high peak values.


Love,
Jens

___

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


Re: ObjC in time-critical parts of the code

2009-01-15 Thread Greg Titus

Jens,

The point of what people are trying to tell you is that the result you  
are getting (3ms per empty Objective-C call) is approximately 500,000  
times longer than the time you ought to be getting (5-6ns). If an  
Objective-C message send took 3 milliseconds (333 method calls per  
second!), no useful software could ever have been written in the  
language.


From your guess at the end of your post, ("message dispatcher  
servicing") it is pretty clear that you don't really know what is  
going on. Blaming the language environment for performance behavior  
that is vastly different than any of the rest of us have ever seen is  
not likely to be useful to you at all. There is something else  
happening with your application.


We're just trying to save you the effort of rewriting and then  
discovering that nothing about the timing problem has changed, because  
you have misidentified the problem.


Good luck,
 Greg

On Jan 15, 2009, at 11:20 PM, Jens Bauer wrote:


Hi Chris,

The rendering is not choppy in every frame.
I'm already using Shark often (now it's a bit easier just jusing  
Activity Monitor, because it's always running anyway).
I know the Microseconds() call by heart, and there's nothing wrong  
with it; it does work very well, and does not use much CPU-time.
I doubt that the performance tools are microsecond accurate; in my  
case, it's important to go down to the millisecond level, since I'm  
about to go 60 FPS, and would like my entire operation to stay at  
least below 5ms (actually it uses 0.4 ms).



Love,
Jens

On Jan 16, 2009, at 01:32, Chris Hanson wrote:

Rather than cobble together your own measurement infrastructure  
using old Carbon calls and NSLog, I recommend in the strongest  
possible terms that you measure your application's performance  
using purpose-built profiling and analysis tools like Shark and  
Instruments.


Performance measurement may seem simple at first glance but it can  
be very subtly hard to get right. That's why tools for it are  
supplied with Xcode, and why they need explicit support from the  
operating system.


-- Chris

On Jan 15, 2009, at 2:16 PM, Jens Bauer   
wrote:



Hi all,

I just want to let you know that I discovered I did a terrible  
mistake today.
In other words: you don't have to learn from your own mistakes, if  
you can learn from mine. =)


I investigated this, because my rendering was choppy.

The code...

- (void)renderObject
{
}

- (void)renderAll
{
 UnsignedWideus;
 doubletime;

 Microseconds(&us);
 time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo);
 [self renderObject];

 Microseconds(&us);
 time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo) -  
time;


 NSLog(@"time:%.3fms", time * 0.001);
}

..often used around 3ms for the empty method "-renderObject".
It gave me the terrible result of up to 21ms spent in the empty  
method!



-So I'd like to let you know that it's sometimes good to think "do  
I really need this method?"
I will be rewriting around 8 of my large files for doing some  
rendering, so they will be using C-routines instead of ObjC  
methods, since I'm using them in a real-time environment.


My guess is that the message dispatcher probably needs to do  
something else than servicing *my* application, so I believe it's  
the nature of the environment, not a bug.


___

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/greg%40omnigroup.com

This email sent to g...@omnigroup.com


___

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


Re: ObjC in time-critical parts of the code

2009-01-15 Thread Jens Bauer

Hi Chris,

The rendering is not choppy in every frame.
I'm already using Shark often (now it's a bit easier just jusing  
Activity Monitor, because it's always running anyway).
I know the Microseconds() call by heart, and there's nothing wrong  
with it; it does work very well, and does not use much CPU-time.
I doubt that the performance tools are microsecond accurate; in my  
case, it's important to go down to the millisecond level, since I'm  
about to go 60 FPS, and would like my entire operation to stay at  
least below 5ms (actually it uses 0.4 ms).



Love,
Jens

On Jan 16, 2009, at 01:32, Chris Hanson wrote:

Rather than cobble together your own measurement infrastructure  
using old Carbon calls and NSLog, I recommend in the strongest  
possible terms that you measure your application's performance using  
purpose-built profiling and analysis tools like Shark and Instruments.


Performance measurement may seem simple at first glance but it can  
be very subtly hard to get right. That's why tools for it are  
supplied with Xcode, and why they need explicit support from the  
operating system.


 -- Chris

On Jan 15, 2009, at 2:16 PM, Jens Bauer   
wrote:



Hi all,

I just want to let you know that I discovered I did a terrible  
mistake today.
In other words: you don't have to learn from your own mistakes, if  
you can learn from mine. =)


I investigated this, because my rendering was choppy.

The code...

- (void)renderObject
{
}

- (void)renderAll
{
  UnsignedWideus;
  doubletime;

  Microseconds(&us);
  time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo);
  [self renderObject];

  Microseconds(&us);
  time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo) -  
time;


  NSLog(@"time:%.3fms", time * 0.001);
}

..often used around 3ms for the empty method "-renderObject".
It gave me the terrible result of up to 21ms spent in the empty  
method!



-So I'd like to let you know that it's sometimes good to think "do  
I really need this method?"
I will be rewriting around 8 of my large files for doing some  
rendering, so they will be using C-routines instead of ObjC  
methods, since I'm using them in a real-time environment.


My guess is that the message dispatcher probably needs to do  
something else than servicing *my* application, so I believe it's  
the nature of the environment, not a bug.


___

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


Re: ObjC in time-critical parts of the code

2009-01-15 Thread Jeremy Pereira


On 15 Jan 2009, at 22:16, Jens Bauer wrote:



..often used around 3ms for the empty method "-renderObject".
It gave me the terrible result of up to 21ms spent in the empty  
method!



-So I'd like to let you know that it's sometimes good to think "do I  
really need this method?"
I will be rewriting around 8 of my large files for doing some  
rendering, so they will be using C-routines instead of ObjC methods,  
since I'm using them in a real-time environment.


My guess is that the message dispatcher probably needs to do  
something else than servicing *my* application, so I believe it's  
the nature of the environment, not a bug



I compiled your program into an Xcode project.  I got an answer of  
0.021ms.


I modified the project to call renderObject 1,000 times and I got the  
answer 0.028ms.


The only thing I can think of is that you have confused milliseconds  
and microseconds.






Love,
Jens

___

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/adc%40jeremyp.net

This email sent to a...@jeremyp.net


___

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


Re: ObjC in time-critical parts of the code

2009-01-15 Thread Shawn Erickson
On Thu, Jan 15, 2009 at 2:16 PM, Jens Bauer  wrote:

> - (void)renderAll
> {
>UnsignedWideus;
>double  time;
>
>Microseconds(&us);
>time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo);
>[self renderObject];
>
>Microseconds(&us);
>time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo) -
> time;
>
>NSLog(@"time:%.3fms", time * 0.001);
> }
>
> ..often used around 3ms for the empty method "-renderObject".

#include 
#include 

@interface MyObject : NSObject
@end

@implementation MyObject

- (void) renderObject
{
}

@end

int main(int argc, char* argv[]) {
MyObject* obj = [[MyObject alloc] init];

int i;
UnsignedWide us;
uint64_t startTime;
uint64_t endTime;

Microseconds(&us);
startTime = UnsignedWideToUInt64(us);
[obj renderObject];
Microseconds(&us);
endTime = UnsignedWideToUInt64(us);
NSLog(@"time using Microseconds average for 1 send: %llu ns",
(endTime - startTime) * 1000ULL );

startTime = UnsignedWideToUInt64(UpTime());
[obj renderObject];
endTime = UnsignedWideToUInt64(UpTime());
NSLog(@"time using UpTime average for 1 send: %llu ns", (endTime -
startTime) );

Microseconds(&us);
startTime = UnsignedWideToUInt64(us);
for (i = 0; i < 1; i++) {
[obj renderObject];
}
Microseconds(&us);
endTime = UnsignedWideToUInt64(us);
NSLog(@"time using Microseconds average for 1 sends: %llu ns",
(endTime - startTime) / 10ULL );

startTime = UnsignedWideToUInt64(UpTime());
for (i = 0; i < 1; i++) {
[obj renderObject];
}
endTime = UnsignedWideToUInt64(UpTime());
NSLog(@"time using UpTime average for 1 sends: %llu ns",
(endTime - startTime) / 1ULL );
}

[0:560] > gcc -framework Foundation -framework CoreServices Test.m; ./a.out
2009-01-15 17:45:57.233 a.out[42285:10b] time using Microseconds
average for 1 send: 22000 ns
2009-01-15 17:45:57.235 a.out[42285:10b] time using UpTime average for
1 send: 673 ns
2009-01-15 17:45:57.236 a.out[42285:10b] time using Microseconds
average for 1 sends: 7 ns
2009-01-15 17:45:57.237 a.out[42285:10b] time using UpTime average for
1 sends: 7 ns

-Shawn
___

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


Re: ObjC in time-critical parts of the code

2009-01-15 Thread Shawn Erickson
On Thu, Jan 15, 2009 at 2:16 PM, Jens Bauer  wrote:

> My guess is that the message dispatcher probably needs to do something else
> than servicing *my* application, so I believe it's the nature of the
> environment, not a bug.

This statement isn't even close to being correct. You really should
step back and measure you performance issue using proper tools before
you waste your time rewriting things for no reason (and likely no
gain).

-Shawn
___

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


Re: ObjC in time-critical parts of the code

2009-01-15 Thread Chris Hanson
Rather than cobble together your own measurement infrastructure using  
old Carbon calls and NSLog, I recommend in the strongest possible  
terms that you measure your application's performance using purpose- 
built profiling and analysis tools like Shark and Instruments.


Performance measurement may seem simple at first glance but it can be  
very subtly hard to get right. That's why tools for it are supplied  
with Xcode, and why they need explicit support from the operating  
system.


  -- Chris

On Jan 15, 2009, at 2:16 PM, Jens Bauer  wrote:


Hi all,

I just want to let you know that I discovered I did a terrible  
mistake today.
In other words: you don't have to learn from your own mistakes, if  
you can learn from mine. =)


I investigated this, because my rendering was choppy.

The code...

- (void)renderObject
{
}

- (void)renderAll
{
   UnsignedWideus;
   doubletime;

   Microseconds(&us);
   time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo);
   [self renderObject];

   Microseconds(&us);
   time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo) -  
time;


   NSLog(@"time:%.3fms", time * 0.001);
}

..often used around 3ms for the empty method "-renderObject".
It gave me the terrible result of up to 21ms spent in the empty  
method!



-So I'd like to let you know that it's sometimes good to think "do I  
really need this method?"
I will be rewriting around 8 of my large files for doing some  
rendering, so they will be using C-routines instead of ObjC methods,  
since I'm using them in a real-time environment.


My guess is that the message dispatcher probably needs to do  
something else than servicing *my* application, so I believe it's  
the nature of the environment, not a bug.



Love,
Jens

___

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/cmh%40me.com

This email sent to c...@me.com

___

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


Re: ObjC in time-critical parts of the code

2009-01-15 Thread Michael Ash
On Thu, Jan 15, 2009 at 5:16 PM, Jens Bauer  wrote:
> Hi all,
>
> I just want to let you know that I discovered I did a terrible mistake
> today.
> In other words: you don't have to learn from your own mistakes, if you can
> learn from mine. =)
>
> I investigated this, because my rendering was choppy.
>
> The code...
>
> - (void)renderObject
> {
> }
>
> - (void)renderAll
> {
>UnsignedWideus;
>double  time;
>
>Microseconds(&us);
>time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo);
>[self renderObject];
>
>Microseconds(&us);
>time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo) -
> time;
>
>NSLog(@"time:%.3fms", time * 0.001);
> }
>
> ..often used around 3ms for the empty method "-renderObject".
> It gave me the terrible result of up to 21ms spent in the empty method!

If you're measuring an average of 3ms for an empty message send then
you're doing something really wrong. On a modern Mac you might see an
average of 5 *nano*seconds to call an empty ObjC method. The ObjC
messaging system has an overhead of perhaps a dozen CPU cycles per
invocation. It is utterly negligible in this sort of situation, and in
fact it will be essentially impossible to measure a single invocation.
The only good way to measure it is to perform at least several million
of them in a loop, then measure the total time.

Every programmer should have an idea of how long various typical
operations take to run, which is why I built this list:

http://www.mikeash.com/?page=pyblog/performance-comparisons-of-common-operations-leopard-edition.html

Without knowing more, it's hard to say *what* is going wrong for you,
but something definitely is, as your numbers are about a million times
too large. Maybe your method isn't as empty as you think, or maybe
your measurement isn't actually producing the correct values.

> -So I'd like to let you know that it's sometimes good to think "do I really
> need this method?"
> I will be rewriting around 8 of my large files for doing some rendering, so
> they will be using C-routines instead of ObjC methods, since I'm using them
> in a real-time environment.

Really, don't do this. The overhead of ObjC is important in some
situations, but it's not *that* important.

> My guess is that the message dispatcher probably needs to do something else
> than servicing *my* application, so I believe it's the nature of the
> environment, not a bug.

This doesn't really make sense. The dispatcher lives in libobjc which
in turn gets loaded into each process individually. You aren't sharing
your dispatcher with any other processes. The dispatcher is just a
plain old C function (actually written in assembly, but close enough)
that gets called by your code and which in turn calls the
implementation of the correct method, it's nothing magical.

Mike
___

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


Re: ObjC in time-critical parts of the code

2009-01-15 Thread Jean-Daniel Dupas


Le 15 janv. 09 à 23:16, Jens Bauer a écrit :


Hi all,

I just want to let you know that I discovered I did a terrible  
mistake today.
In other words: you don't have to learn from your own mistakes, if  
you can learn from mine. =)


I investigated this, because my rendering was choppy.

The code...

- (void)renderObject
{
}

- (void)renderAll
{
UnsignedWideus;
double  time;

Microseconds(&us);
time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo);
[self renderObject];

Microseconds(&us);
	time = ((double) us.hi) * 65536.0 * 65536.0 + ((double) us.lo) -  
time;


NSLog(@"time:%.3fms", time * 0.001);
}

..often used around 3ms for the empty method "-renderObject".
It gave me the terrible result of up to 21ms spent in the empty  
method!



-So I'd like to let you know that it's sometimes good to think "do I  
really need this method?"
I will be rewriting around 8 of my large files for doing some  
rendering, so they will be using C-routines instead of ObjC methods,  
since I'm using them in a real-time environment.


My guess is that the message dispatcher probably needs to do  
something else than servicing *my* application, so I believe it's  
the nature of the environment, not a bug.



Got this with Test.m:

elapsed: 7257238014 ns (7.257238 ns per call)

- Test.m -
#import 
#include 

@interface Foo : NSObject {

}

- (void)nop;

@end

@implementation Foo

- (void)nop {}

@end


int main(int argc, char **argv) {
  Foo *foo = [[Foo alloc] init];
  uint64_t delta = mach_absolute_time();
  for (NSUInteger idx = 0; idx < 10; idx++) {
[foo nop];
  }
  delta = mach_absolute_time() - delta;
  [foo release];

  /* convert to nano */
  mach_timebase_info_data_t sTimebaseInfo;
  mach_timebase_info(&sTimebaseInfo);

  delta = delta * sTimebaseInfo.numer / sTimebaseInfo.denom;
  fprintf(stderr, "elapsed: %qu ns (%f ns per call)\n", delta,  
delta / 10.0);


return 0;
}



___

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