On Apr 15, 2014 9:13 PM, "Franklin? Lee"
Well, a little effort on the last ditch.
Like I said before, I don't see the need for modification to mean that
this can't be made to work. I still think it would be possible to make the InternDict start off with the knowledge of the keys, and then upon attempt to add, it can either:
- use a second internal array to store non-str keys (or just non-interned
keys? or just all new keys?), and doing a check to see, "Am I trying to access a str key?". The hash would have an index into one of the two arrays. If it's storing new str keys in this new array (as opposed to only non-str keys), the interpreter would flatten again upon **blowup.
(Example indexing for the second array: -1 is the first NEW element, then
-2... If you ask for an element, and it's a str, then intern it and hash its interned ID and look it up on the hash table. If it's negative, it's in the second array. If you ask for the ordered keys, it will trek through the original array forwards, then the newarray backwards. Also, the standard case doesn't need to worry about lookup overhead, because it only looks for a second array if the hash table reports a negative index. It does need to check the second-array pointer if it's getting the elements in order.)
- internally convert to a regular dict. This is undesirable, because it
would lose order, which would be surprising to users.
and upon delete, it would have to deal with deleting two entries (hash
table and array). Fortunately, it wouldn't need to shift everything down, probably, and the unpacking call can just get the elements in sorted order.
Both of these, alas, would cause additional overhead on add/delete, and
the first causes extra bookkeeping even without that use (a pointer to a second internal array, even if that pointer is null, and occasional checking of that pointer when working with the whole table; and always intern strings going in). And if the kwargs are an OrderedDict, and not just acting like an ordered dict until you change it, it would have to remember the order of those new members, even if they're not going to be repacked into kwargs, and even if the user doesn't care about the order.
But I don't know enough to say that that's a killer. As in, maybe it
improves the usual case (calls) enough that the harm to the modifying case is cancelled out for big programs. Maybe non-modifying-case speedup + modifying-case slowdown < 0, and maybe if it looks enough like a dict, no user ever has to know. That's about five maybes, for those not keeping track.
On Tue, Apr 15, 2014 at 9:01 AM, Eric Snow
wrote:
On Mon, Apr 14, 2014 at 10:12 PM, Franklin? Lee
wrote: Point is, again, I don't know that it won't be faster. You seem to
know that
it won't be faster, but I don't see you saying that there CAN'T be such cleverness when kwargs are nice and forwarded nicely, even with deletions or additions allowed.
The point is moot. The object into which uncollected kwargs is bound must be a complete mapping instance that supports any type of key. We certainly *initialize* it with string keys, but once it is bound in the function, code is free to do anything that works with a normal dict (think Liskov). Limiting capability is a non-starter.
That said, thanks for posting the idea. It wasn't all that unfeasible (unlike other ideas that land here <wink>), even if it ultimately wasn't acceptable.
You can also "upgrade" the interned dict upon addition Kwargs.__class__ = dict Only in C and be careful ...