Ускорение в петлеобразных структурах

Я замечаю интересное поведение, когда дело доходит до составления списков по-разному. .append занимает больше времени, чем списки, которые занимают больше времени, чем map , как показано в следующих экспериментах:

 def square(x): return x**2 def appendtime(times=10**6): answer = [] start = time.clock() for i in range(times): answer.append(square(i)) end = time.clock() return end-start def comptime(times=10**6): start = time.clock() answer = [square(i) for i in range(times)] end = time.clock() return end-start def maptime(times=10**6): start = time.clock() answer = map(square, range(times)) end = time.clock() return end-start for func in [appendtime, comptime, maptime]: print("%s: %s" %(func.__name__, func())) 

Python 2.7:

 appendtime: 0.42632 comptime: 0.312877 maptime: 0.232474 

Python 3.3.3:

 appendtime: 0.614167 comptime: 0.5506650000000001 maptime: 0.57115 

Теперь я прекрасно понимаю, что range в python 2.7 строит список, поэтому я понимаю, почему существует несоответствие между временами соответствующих функций в python 2.7 и 3.3. Меня больше беспокоят относительные временные различия между append , list-comprehension и map .

Во-первых, я считал, что это может быть связано с тем, что понимание map и списков может позволить интерпретатору знание конечного размера результирующего списка, что позволит интерпретатору malloc достаточно большого массива C под капотом для хранения списка. По этой логике, понимание списков и map должны занимать примерно столько же времени.
Однако данные синхронизации показывают, что в python 2.7, listcomps составляют ~ 1.36x так же быстро, как append , а map ~ 1.34x так же быстро, как listcomps.
Более любопытно, что в python 3.3, listcomps составляют ~ 1.12x так же быстро, как append , а map на самом деле медленнее, чем listcomps.

Очевидно, что map и списокcomps не «играют по тем же правилам»; ясно, что карта использует то, чего нет в списке.
Может ли кто-нибудь пролить свет на причину разницы в этих значениях времени?

One Solution collect form web for “Ускорение в петлеобразных структурах”

Во-первых, в python3.x map возвращает iterable , а не список, поэтому объясняется ускорение 50kx. Чтобы сделать это справедливым, в python3.x вам понадобится list(map(...)) .

Во-вторых, .append будет медленнее, потому что каждый раз через цикл интерпретатор должен искать список, тогда ему нужно найти функцию append в списке. Этот дополнительный поиск .append не должен происходить со списком-компасом или картой.

Наконец, со списком-пониманием, я считаю, что square функции нужно искать на каждом шагу вашего цикла. С картой он отображается только при вызове карты, поэтому, если вы вызываете функцию в своем понимании списка, map обычно будет быстрее. Обратите внимание, что при составлении списка обычно map с помощью lambda функции.

  • Почему существует разница между созданием класса в python 2.7 и производительности python 3.4
  • Многопроцессы становятся зомбическими процессами при увеличении итераций. В чем преимущество mp.Queue () в Manager.list ()?
  • Группировка ключей словаря Python в виде списка и создание нового словаря с этим списком в качестве значения
  • Мертвый простой пример использования многопроцессорной очереди, пула и блокировки
  • Сумма Python значений ASCII всех символов в строке
  • Список на python, добавляющий всегда одно и то же значение
  • Как использовать функцию обратного вызова в python?
  • Согласовать каждый элемент списка с каждым элементом второго списка
  • Как удалить словари с дублирующимися значениями из вложенного словаря
  • Привязка кривой Гаусса к данным в python
  • глобальная переменная в основном не распознается в другой функции в python
  • Python - лучший язык программирования в мире.