Почему `{* l}` быстрее `set (l)` - наборы питонов (не только для наборов, для всех последовательностей) - PullRequest
0 голосов
/ 09 ноября 2018

Итак, вот мои времена:

>>> import timeit
>>> timeit.timeit(lambda: set(l))
0.7210583936611334
>>> timeit.timeit(lambda: {*l})
0.5386332845236943

Почему, мое мнение было бы равным, но это не так.

Так что распаковка происходит быстро из этого примера, верно?

1 Ответ

0 голосов
/ 09 ноября 2018

По той же причине [] быстрее, чем list(); Интерпретатор включает выделенную поддержку операций на основе синтаксиса, которые используют специализированные пути кода, в то время как вызовы конструктора включают:

  1. Загрузка конструктора из встроенной области (требуется пара dict поисков, один в глобальной области, затем другой во встроенной области при сбое)
  2. Требуется диспетчеризация через универсальные механизмы вызываемой диспетчеризации и универсальный код синтаксического анализа аргументов, и все это намного дороже, чем однобайтовый код, который считывает все свои аргументы из стека в виде массива C

Все эти преимущества относятся к фиксированным накладным расходам; big-O обоих подходов одинаковы, поэтому {*range(10000)} не будет заметно / надежно быстрее, чем set(range(10000)), потому что фактические строительные работы значительно превышают накладные расходы по загрузке и вызову конструктора через общую диспетчеризацию.

...