Skip to content Skip to sidebar Skip to footer

Does Reusing A List Slice To Get Length Cost Additional Memory?

I proposed a something in a comment in this answer. Martijn Pieters said that my suggestion would be memory intensive, and he's usually right, but I like to see things for myself,

Solution 1:

Yes, additional memory will be reserved for a new list object that is created just for the slice.

However, the list object is discarded again after querying the length. You just created a list object just to calculate how long half a list would be.

Memory allocations are relatively expensive, even if you then discard the object again. It is that cost I was referring to, while you are looking for a permanent memory footprint increase. However transient the list object might be, you still needed to allocate memory for this object.

The cost is immediately apparent when you use timeit to compare the two approaches:

>>>import timeit>>>defcalculate(alist):...    (1 + len(alist)) // 2...>>>defallocate(alist):...len(alist[::2])...>>>testlist = range(10**5)>>>timeit.timeit('f(testlist)', 'from __main__ import testlist, calculate as f', number=10000)
0.003368854522705078
>>>timeit.timeit('f(testlist)', 'from __main__ import testlist, allocate as f', number=10000)
2.7687110900878906

The slice only has to create a list object and copy across half the references, but that operation takes more that 800 times as long as simply calculating the length from the existing list.

Note that I actually had to reduce the timeit repetition count; the default 1 million repetitions was going to take an additional 4.5 minutes. I wasn't going to wait that long, while the straight calculation took a mere 0.18 seconds.

Post a Comment for "Does Reusing A List Slice To Get Length Cost Additional Memory?"