Re: WTF? How can this work?
Re: WTF? How can this work?
- Subject: Re: WTF? How can this work?
- From: tyler <email@hidden>
- Date: Wed, 22 Aug 2001 09:35:40 -0700
This was really well put and informative and I appreciate the time you
spent to type it all in!
Thanks!
tyler
On Sunday, August 19, 2001, at 06:12 PM, Chris Kane wrote:
On Sunday, August 19, 2001, at 01:05 PM, Erik M. Buck wrote:
Remind me what new features were added to Foundation to justify the
changes.
Other than
NSURL and related
Key-value coding & NSClassDescription
Scripting
only misc tweaks have been made to Foundation's API. There are other
more indirect features, like string objects now handling more encodings
and the like. Now, English-using developers running in English may not
care, but now handling Korean, Simplified Chinese, and Traditional
Chinese (and others) is very nice for Korean and Chinese speakers. (I
suppose that opens up additional potential markets for 3rd party
developers.)
But I don't see that any correlation between implementation and
features is required here. Sometimes new feature helps o
From a Cocoa developer's point of view,
how did the implementation changes and the introduction of Core
Foundation
dramatically improve the frameworks ?
I don't understand this fetish some people have for blaming
CoreFoundation. How was this conclusion arrived at? Yes, if you
sample or profile (though timings with that latter shouldn't be trusted
with all the non-profilable libraries on the system), you see most of
the time spent in CoreFoundation -- because the Foundation
implementation uses that. If Foundation didn't, all the time would be
in Foundation and people would say "Geez, Foundation is slow".
nm the OpenStep 4.2 binary (or Mac OS X Server 1.x) and grep for
'NSSimple'. Among the hits will be NSSimpleSet and
NSSimpleDictionary. These were the C-API implementations of
NSDictionary, NSMutableDictionary, NSSet, NSMapTable, and so on. What
CoreFoundation did was take those and drop them into another framework.
Now, we've certainly made implementation changes since then. I have
this feeling (but don't actually know now) that the secondary hash
function in the case of sets and dictionaries may be more subject to
catastrophic degradation in some cases than the previous one was, even
though it is often better in the general case. And, since the backing
store of mutable dictionaries accounts for a good chunk of typical
apps' heaps, we discarded one CPU-related optimization for a memory
optimization, and the dictionary type things now take about 2/3rds (and
sets 1/2) of the memory they used to OpenStep; however, the equality
function (-isEqual:) for the keys will now tend to be called more (how
much more depends on how good the key hash is). [System-wide memory
use is in a much more critical state than CPU time.] Those are
examples.
But these are changes we might have made in Foundation's implementation
had the implementation remained there. They have nothing to do with
CoreFoundation particularly.
Indeed, there have been other benefits to CoreFoundation:
- NSConcreteDictionary and NSConcreteMutableDictionary used to have
many overridden methods with the same implementation, but since the two
classes didn't inherit from one another, they had copy-paste copies of
the methods; so much for reuse
- often hacks with overridden -retain/-release methods were required to
deal with reference cycles due to retaining collections; now with CF
collections that can be configured (1) to allow NULL and (2) not retain
objects, some code has been able to be simplified (I'm thinking of
CFArray here mostly)
- if we hadn't pulled the run loop model down to CoreFoundation, we
would have either had two separate event subsystems, or one designed
more around the models of Carbon which NSRunLoop would have had to
adapt to (if there were to be only one) and who knows what might have
been lost in such a transition; NSRunLoop ends up on a much more
capable and feature-ful base
- Cocoa paradigms have been brought to Carbon developers, which eases
the migration path for them; if you've already parked yourself in the
Cocoa camp and aren't budging, this doesn't directly benefit you (in
fact, you may have to wade through more "what do the square brackets
mean?" messages on the mailing lists), and may mean more competition
starting out on the 10th floor ;-);
[however, if easing the transition results in more Cocoa programmers
out there, that may have indirect benefits; if one assumes for a moment
that Apple is influenced by microeconomic-type considerations, then
more Cocoa developers might cause more relatively more documentation
resources to be applied to Cocoa doc than Carbon doc (which is in a
pretty good state); or, you want ObjC APIs to QuickTime? the best
people to do those are the experts in QuickTime, the QuickTime group,
and the more Cocoa developers the more likely that might be]
[since most of you are probably not on the Carbon lists on which
this has happened: a fun anecdote here is that some Carbon developers
in the past couple years have complained that some Carbon APIs are
wrong or bad because they don't follow the CoreFoundation
Create/Copy/Get memory ownership conventions or use reference counting,
and have requested that new APIs be provided which do.]
Yes, there have been a few new bugs in Foundation which were actually
bugs in CoreFoundation. But there have also been some bugs fixed due
to that transition.
And, because CF's collections support more features than NS collections
(such as being able to be used from CFM apps, which doesn't apply to or
benefit the ObjC API), there are some performance hits due to that.
But there have also been some good recoveries of those hits in 10.1
(even while retaining the features). And some more coming after 10.1.
Now why convert NS implementations to use CF implementations? Well,
besides the simple answers of less code to maintain and less hot code
required to run (instead of a hot NSDictionary implementation and a hot
CFDictionary implementation, there's just a hot CFDictionary
implementation and a tiny hot NSDictionary implementation), a common
implementation gives us a bigger lever to make improvements; if you
think that a novel approach to hashing done in CoreFoundation would not
necessarily be done also to Foundation (after all, aren't you arguing
"why was something fixed which wasn't broken?"); but Foundation doing
reasonably doesn't mean there wasn't room for improvement (see DO
example below too). There is the possibility of indirect leveraging of
work done on the open-sourced CoreFoundation as well (though useful
submissions have been rare so far).
And if anyone wants to complain about the speed of the CF bits that
Foundation is based on, they're all (except CFPreferences) in Darwin to
look at, compile, test, and tune to your hearts' content.
The performance of Foundation is now
atrocious. How could things be slowed down so much ? A 450 MHz G4
performs
worse that a 266MHz Pentium II running substantially the same
Foundation
code. That is embarrassing!
This depends on what you're looking at, and what you're doing. Launch
time has certainly suffered, due to the additional frameworks. Many
operations in dyld are O(N) in the number of libraries (because it was
designed and optimized more for the situation at NeXT).
Also, be wary of getting sucked into the Photoshop
PPC-2x-faster-than-Pentium miasma generated from stage. (Plus remember
that Pentium IIs didn't have the really deep pipelines that are going
to kill the P4. ;-)) Cocoa apps aren't float or integer
computation-bound, they're memory and I/O bound, and they use the
Velocity Engine not at all (unless the developer is doing that
themselves), thus benefit not at all. It may just be more paging which
is hurting the G4. Well, there are so many different and complex
factors here that it's not really worth getting into this rat's nest.
There have been may other changes to the Cocoa stack that don't involve
CoreFoundation. For example, the Scripting feature requires pulling in
new frameworks, though we do that dynamically when needed, but this
also unfortunately pulls in some frameworks indirectly that we don't
need due to the layering of the system. Or, to deal with the HFS file
system, and the additional features it has and/or users expect, we've
had to convert code in Foundation more and more to use the lower layers
of Carbon, which has many internal layers of its own; deleting a file
is not your simple unlink() anymore. [Some backtraces nowdays can be
quite breath-taking.] Or, to deal with the Mach 3.0 conversion, the
built-in Mach port-based DO transport was ported, but had to preserve
the old DO semantics in the face of Mach API changes which didn't
preserve the old semantics; it works, but not nearly as quickly as it
might (but why fix it when it works? CFMessagePort, which has more
internal clients than DO, gets the attention [and the number of
external clients may be surpassed DO's by now too, there's no way to
know]; if DO was implemented in the local case to use CFMessagePort,
it'd get indirect attention).
Some of the performance loss has been due to other layers, like the
ObjC runtime. At least problematic optimizations were tossed in 10.0,
in favor of simpler but functioning code. And in a case or two,
optimization has shifted on the CPU vs. memory balance to the memory
side. There are definitely ways to speed up the runtime, if we're
willing to burn the memory. Some very good things have been done in
10.1 to the runtime to speed thing up, particularly launch time spent
in ObjC initialization (some of these were things that could have been
done in OPENSTEP 4.2 too, it's not like they're all things recently
introduced).
Well I could go on with any of these sections, but this message is
already long enough.
Chris Kane
Cocoa Frameworks, Apple
_______________________________________________
cocoa-dev mailing list
email@hidden
http://www.lists.apple.com/mailman/listinfo/cocoa-dev