
On Wed, 24 Jun 2009 06:23:31 am Kristján Valur Jónsson wrote:
Hello there. Please see my feature request: http://bugs.python.org/issue6326
The idea is to speed up the swapping of list elemenst so that a.swap(b) is equivalent to a[:], b[:] = b[:], a[:] but without all the overhead of creating slices, assigning them and so forth. In particular, it can help reduce the cost of creating instances of list subclasses, from raw lists:
class mylist(list): def first(self): return self[0]
m = mylist(source_list)
Is that overhead really significant enough that it needs a special operation to avoid it? In the tracker, you claim a significant performance gain, but I'd like to hear more details.
This certainly creates m, but does so by copying source_list.
Only the pointers, not the objects pointed to. But I'm sure you already know this :)
If all we want to do is turn source_list into a mylist instance, it is much quicker to: m = mylist() m.swap(source_list)
This has a side-effect of turning source_list into an empty mylist. I don't like that one bit.
See the above issue for initial comments, especially concerns on how this can bypass all kind of insertion semantics of list subclasses.
Can you address those concerns? One problem with swap() being a list method is that it allows people to arbitrarily swap the contents of lists around, breaking subclass invariants. I have an alternative suggestion: put the swap into list.__new__, so it can only be done at list initialisation time. list.__new__(cls, source) currently returns an empty list of type cls, which is then initialised by list.__init__(self, source), presumably by copying source. Perhaps list.__new__ could take an additional argument that says "swap the contents of the new list to use source without copying". That means, instead of writing: a = mylist() a.swap([1, 2, 3]) you would put the fast initialisation logic into the class: class mylist(list): def __new__(cls, source): return list.__new__(cls, source, swap=True) def __init__(self, source): pass # avoid calling list.__init__ Existing code should work unchanged if the default for swap is False. -- Steven D'Aprano