Python tuples
(immutable sequences) can be much slower to work with than their mutable cousins, lists
. This surprised me; I would have thought they would have been faster all ’round, as they seem “simpler”. That doesn’t seem to be the case.
Methodology
I ran some simple timing experiments comparing list
and tuple
operations in Python 2.5.1, from inside the PythonWin environment (build 210). I used the timeit module for all tests, running the default 1,000,000 trials.
Creation
If you’re creating a sequence from an explicit set of values, tuples
are much faster to create:
>>> timeit.Timer('[1,2,3,4,5,6,7,8,9]').timeit()
0.6413645024165362
>>> timeit.Timer('(1,2,3,4,5,6,7,8,9)').timeit()
0.050510743951576842
If you’re creating a sequence algorithmically, e.g. from a list comprehension, tuples
are slower to create:
>>> timeit.Timer('[i*2 for i in range(10)]').timeit()
4.1430525274962866
>>> timeit.Timer('tuple(i*2 for i in range(10))').timeit()
11.855401369060489
It takes nearly three times as long to create a short tuple
from a list comprehension as it does to create a list
.
Slices
Tuples
are quicker to slice than lists
:
>>> timeit.Timer('t[:5]', 't = [i*2 for i in range(10)]').timeit()
0.54482657497751319
>>> timeit.Timer('t[:5]', 't = tuple(i*2 for i in range(10))').timeit()
0.25133068111281887
It takes about 1/2 the time to slice a tuple
as it does to slice a list
.
Deletion
However, since tuples
are immutable, it’s very expensive to remove items from them:
>>> timeit.Timer('t[:].remove(6)', 't = [i*2 for i in range(10)]').timeit()
1.007475770140104
>>> timeit.Timer('tuple(e for e in t if e != 6)', 't = tuple(i*2 for i in range(10))').timeit()
7.2336211566225757
Since tuples
have no equivalent to the list.remove()
method, a new tuple
must be constructed that omits the undesired element. For short tuples
, this process can take over 7 times longer than the equivalent list.remove()
call. (Note that the actual difference is even greater, as my test code copies the list
before invoking list.remove()
.)
Summary
In inner loops, the choice between lists
and tuples
can make a big difference in performance. It’s advisable to consider exactly how you plan to use your sequence objects, and choose accordingly.