Пока я читал и искал, что именно вызывает разницу в производительности между циклами и пониманием списка (на основе нижеприведенных простых тестовых примеров, понимание списка быстрее), я обнаружил следующие сообщения здесь, в SO:
Простые тестовые примеры:
def f1():
t = []
for i in range(10000):
t.append(i)
def f2():
t = [i for i in range(10000)]
Почему понимание списка намного быстрее, чем добавление к списку?
Являются ли списки понимания и функциональные функции быстрее, чем «циклы for»?
Как я понимаю из приведенных выше сообщений, основные отличия заключаются в следующем:
- For l oop строит список, но список понимание не
- Для l oop загружает метод добавления на каждой итерации, но понимание списка не
Затем я использовал дизассемблер, чтобы увидеть детали, и я увидел следующие шаги для следующий блок кода:
Код:
def f2():
t = [i for i in range(10000)]
dis.dis(f2)
Результат дизассемблера:
0 BUILD_LIST
2 LOAD_FAST
4 FOR_ITER
6 STORE_FAST
8 LOAD_FAST
10 LIST_APPEND
12 JUMP_ABSOLUTE
14 RETURN_VALUE
На основе Python делать c; 0 BUILD_LIST
создает список, а 10 LIST_APPEND
использует метод добавления в отличие от вышеупомянутых связанных сообщений:
LIST_APPEND(i)
Calls list.append(TOS[-i], TOS). Used to implement list comprehensions.
BUILD_LIST(count)
Works as BUILD_TUPLE, but creates a list.
Я не мог понять, что мне здесь не хватает. Отличается ли способ понимания списка и добавления от l oop, потому что в любом случае LIST_APPEND
содержит метод append
, а BUILD_LIST
создает список? а может причина разницы в производительности в другом? Может кто-нибудь прояснить это для меня?
Спасибо!