Есть ли разница в производительности между кортежами и списками, когда дело доходит до создания и извлечения элементов?
python
performance
list
tuples
python-internals
Readonly
источник
источник
Ответы:
dis
Модуль разбирает байт - код для функции и полезно , чтобы увидеть разницу между кортежами и списками.В этом случае вы можете видеть, что при доступе к элементу генерируется идентичный код, но назначение кортежа происходит намного быстрее, чем назначение списка.
источник
ListLike
с классом,__getitem__
который делает что-то ужасно медленное, затем разберитеx = ListLike((1, 2, 3, 4, 5)); y = x[2]
. Байт-код будет больше похож на приведенный выше пример кортежа, чем на пример списка, но действительно ли вы считаете, что производительность будет аналогичной?В целом, вы можете ожидать, что кортежи будут немного быстрее. Однако вы должны обязательно протестировать ваш конкретный случай (если разница может повлиять на производительность вашей программы - помните: «преждевременная оптимизация - корень всего зла»).
Python делает это очень просто: время - твой друг.
и...
Так что в этом случае создание экземпляра почти на порядок быстрее для кортежа, но доступ к элементу на самом деле несколько быстрее для списка! Поэтому, если вы создаете несколько кортежей и обращаетесь к ним много-много раз, на самом деле может быть быстрее использовать списки.
Конечно, если вы хотите изменить элемент, список определенно будет быстрее, так как вам нужно будет создать целый новый кортеж, чтобы изменить один его элемент (так как кортежи неизменны).
источник
python -m timeit "x=tuple(xrange(999999))"
противpython -m timeit "x=list(xrange(999999))"
. Как и следовало ожидать, для создания кортежа требуется немного больше времени, чем для списка.-s "SETUP_CODE"
Выполняются до фактического таймерного кода.Резюме
Кортежи имеют тенденцию работать лучше, чем списки почти в каждой категории:
1) Кортежи могут быть постоянно сложены .
2) Кортежи можно использовать повторно вместо копирования.
3) Кортежи компактны и не перераспределяют.
4) Кортежи напрямую ссылаются на свои элементы.
Кортежи могут быть постоянно сложены
Кортежи констант могут быть предварительно вычислены оптимизатором глазков Python или AST-оптимизатором. Списки, с другой стороны, создаются с нуля:
Кортежи не нужно копировать
Бег
tuple(some_tuple)
сразу возвращается сам. Поскольку кортежи являются неизменяемыми, их не нужно копировать:Напротив,
list(some_list)
требует , чтобы все данные были скопированы в новый список:Кортежи не перераспределяют
Поскольку размер кортежа фиксирован, он может храниться более компактно, чем списки, которые необходимо перераспределить, чтобы сделать операции append () эффективными.
Это дает кортежам хорошее космическое преимущество:
Вот комментарий от Objects / listobject.c, который объясняет, что делают списки:
Кортежи ссылаются непосредственно на свои элементы
Ссылки на объекты включаются непосредственно в объект кортежа. Напротив, списки имеют дополнительный уровень косвенности к внешнему массиву указателей.
Это дает кортежам небольшое преимущество в скорости для индексированных поисков и распаковки:
Вот как
(10, 20)
хранится кортеж :Вот как
[10, 20]
хранится список :Обратите внимание, что объект кортежа включает два указателя данных напрямую, в то время как объект списка имеет дополнительный уровень косвенности к внешнему массиву, содержащему два указателя данных.
источник
Internally, tuples are stored a little more efficiently than lists, and also tuples can be accessed slightly faster.
Как вы можете объяснить результаты ответа Д.Ф.?tuple(some_tuple)
возвращаетsome_tuple
себя, только еслиsome_tuple
является хэшируемым - когда его содержимое является рекурсивно неизменным и хэшируемым. В противном случаеtuple(some_tuple)
возвращает новый кортеж. Например, когдаsome_tuple
содержит изменяемые элементы.Кортежи, будучи неизменными, более эффективны для памяти; списки, для эффективности, перераспределяют память, чтобы разрешить добавления без константы
realloc
s. Итак, если вы хотите перебирать постоянную последовательность значений в вашем коде (напримерfor direction in 'up', 'right', 'down', 'left':
), кортежи предпочтительнее, так как такие кортежи предварительно рассчитываются во время компиляции.Скорости доступа должны быть одинаковыми (они оба хранятся в памяти в виде смежных массивов).
Но
alist.append(item)
гораздо предпочтительнее,atuple+= (item,)
когда вы имеете дело с изменчивыми данными. Помните, что кортежи должны рассматриваться как записи без имен полей.источник
Вы также должны рассмотреть
array
модуль в стандартной библиотеке, если все элементы в вашем списке или кортеже относятся к одному и тому же типу C. Это займет меньше памяти и может быть быстрее.источник
Вот еще один маленький ориентир, просто ради этого ..
Давайте усредним это:
Вы можете назвать это почти безрезультатным.
Но, конечно, кортежи заняли
101.239%
время или1.239%
дополнительное время, чтобы выполнить работу по сравнению со списками.источник
Кортежи должны быть немного более эффективными и поэтому быстрее, чем списки, потому что они неизменяемы.
источник
Основная причина высокой эффективности чтения Tuple заключается в том, что он неизменен.
Почему неизменяемые объекты легко читать?
Причина в том, что кортежи могут храниться в кеш-памяти, в отличие от списков. Программа всегда считывает из памяти ячейки списков, так как она изменчива (может измениться в любое время).
источник