Re: CFMutableDictionary Capacity
Re: CFMutableDictionary Capacity
- Subject: Re: CFMutableDictionary Capacity
- From: Wade Tregaskis <email@hidden>
- Date: Tue, 09 Aug 2011 23:11:25 -0700
>>> According the doc, the parameter "capacity" in function CFDictionaryCreateMutable() sets the *maximum number* of key-value pairs which can be inserted into the container. That is, it's not an *initial* capacity.
>>
>> I think that was a mistake in the docs. The comment in CFDictionary.h in the 10.7 SDK says:
It is now. In 10.3 (the first release in which CF was open source) this parameter was actually obeyed, and you'd crash [by failed assert] if you tried to exceed that capacity. Sometime since then that changed - in 10.7 the capacity parameter is almost completely ignored; it's merely asserted to be non-negative.
>> Since CFDictionary and NSDictionary have the same implementation under the hood, I think the capacity will have the same effect at runtime whichever API you use.
Not necessarily. CF and NS objects can actually be different even though they are toll-free bridged and ostensibly appear identical. Whether you create them via the CF or NS APIs is generally what makes that difference. I wouldn't worry about it in general, though.
And that said, I don't know if nor to what extent it applies in the case of CF/NSDictionary.
> Nonetheless, when defining a mutable dictionary with CF functions, the subsequent insertions take far more time than when using Foundation, e.g.:
>
> CFMutableDictionaryRef o =
> #if USE_CF
> CFDictionaryCreateMutable(NULL, count,
> &kCFTypeDictionaryKeyCallBacks,
> &kCFTypeDictionaryValueCallBacks);
> #else
> CFMutableDictionaryRef([[NSMutableDictionary alloc] initWithCapacity:count]);
> #endif
You could also try calling _CFDictionarySetCapacity on your new dictionary, in your CF path. That will actually pre-allocate space for the given number of entries (without restricting you to that many, at least not in 10.7). That might be the difference between the two. I suspect it is, but it could also be a difference of initial hashing algorithms (there are three available to use, but you can't choose which*), different callbacks internally, or other factors.
In any case, you should try it and see what difference it makes. It's exported, but SPI. If it's not defined anywhere, you can define it manually as below.
extern void _CFDictionarySetCapacity(CFMutableDictionaryRef dictionary, CFIndex capacity);
You could also try the same thing on the NSMutableDictionary - try setting it to both your known count but also a small number (not zero nor one though, as those are treated specially, not literally).
* = At least, not via any API I'm aware of, and certainly not after creation. You could drop down to using CFBasicHash directly and create it how you like, of course. CFBasicHash is the actual implementation of CFDictionary; they are "the same". However, the CFDictionary level of API does do a few special things - most obviously, setting "special bits" at creation time which ensure the collection works correctly if it contains non-CF types (well, more specifically, if you use NULL for any of the key or value callbacks). Long story short, it's almost certainly not worth it. :)
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden