gpt4 book ai didi

python - 为什么列出 `my_list+[' foo' ]` faster than ` new_list = list(my_list); python 中的 new_list.append ('foo' )`?

转载 作者:行者123 更新时间:2023-12-01 05:03:10 24 4
gpt4 key购买 nike

在编写一些 Python 代码时,我偶然发现了一些令我惊讶的事情。我正在考虑两种复制列表的方法,然后向副本中添加一个元素:

# I thought this would be clean-looking but slow since it creates an extra one element list, ['foo']
mylist = range(4)
newlist_0 = mylist + ['foo']
print newlist_0 # [0, 1, 2, 3, 'foo']

# I thought this would be faster
newlist_1 = list(mylist)
newlist_1.append('foo')
print newlist_1 # [0, 1, 2, 3, 'foo']

令人惊讶的是,第一种方法不仅美观而且速度更快。我跑了:

import timeit
for stmt in ['newlist_0 = mylist + ["foo"]', 'newlist_1 = list(mylist); newlist_1.append("foo")']:
print "For statement {:50} timeit results are {}".format(stmt, timeit.repeat(setup='mylist = range(4)', stmt=stmt))

并得到这个输出:

For statement newlist_0 = mylist + ["foo"]                       timeit results are [0.29012012481689453, 0.3021109104156494, 0.32175779342651367]
For statement newlist_1 = list(mylist); newlist_1.append("foo") timeit results are [0.39945101737976074, 0.39692091941833496, 0.38529205322265625]

突然我偶然发现了this question讨论 list(lst) 复制列表比 lst[:] 慢的事实,但切换到使用 [:] 复制mylist 不会改变任何东西。

最佳答案

我们来看看反汇编。您的第一个方法在 Python 2.7 字节码中如下所示:

          0 LOAD_FAST                0 (mylist)
3 LOAD_CONST 1 ('foo')
6 BUILD_LIST 1
9 BINARY_ADD

第二种方法如下所示:

          0 LOAD_GLOBAL              0 (list)
3 LOAD_FAST 0 (mylist)
6 CALL_FUNCTION 1
9 STORE_FAST 1 (newlist_1)

12 LOAD_FAST 1 (newlist_1)
15 LOAD_ATTR 1 (append)
18 LOAD_CONST 1 ('foo')
21 CALL_FUNCTION 1

根据反汇编的比较,一些会使后者变慢的事情:

  1. list 必须从全局命名空间加载。

  2. append 必须从列表对象加载。

  3. 您支付两次调用开销,而不是一次。

简短的回答是,Python 字节码有非常简洁有效的方法来存储 ['foo'] 等短列表并执行二进制操作。

关于python - 为什么列出 `my_list+[' foo' ]` faster than ` new_list = list(my_list); python 中的 new_list.append ('foo' )`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25610983/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com