• 注册
  • 查看作者
  • 简单分析:为什么[]比list()快?

    分享一篇文章:

    本文来自“为什么Python”系列,请查看所有文章

    在日常使用Python时,我们经常需要创建一个列表。相信大家都很熟练。

    #方法1:使用成对方括号语法

    list_a=[]

    #方法2:使用内置列表()

    list_b=list()

    以上两种写法你经常用哪一种?你想过他们的不同吗?

    让我们开门见山,直接抛出这篇文章的问题:两种创建列表的 [] 与 list() 写法,哪一个更快呢,为什么它会更快呢?

    注意:为了简化问题,我们以创建空列表为例进行分析。欲了解更多列表的介绍和使用说明,可以查看本文

    1 、 [] 是 list() 的三倍快

    对于第一个问题,您可以简单地使用timeit模块的timeit()函数来计算:

    导入时间

    timeit.timeit('[]',number=10**7)

    timeit.timeit('list()',number=10**7)

    如上图所示,当其中每一个被调用1000万次时,[]的创建方法只需要0.47秒,而list()的创建方法需要1.75秒,所以后者需要的时间是前者的3.7倍!

    这回答了刚才的问题:创建空列表时,[] 要比 list() 快不少。

    注意:timeit()函数的效率与运行环境有关,每次执行的结果会略有不同。我用Python3.8版本3.8做了几次实验,[]的速度是list()的三倍多一点。

    2 、list() 比 [] 执行步骤多

    那么,我们继续分析第二个问题:为什么[]更快?

    这一次,我们可以使用dis模块的dis()函数来查看两者执行的字节码之间的区别:

    从dis导入dis

    dis('[]')

    dis('list()')

    如上图所示,[]的字节码有两条指令(BUILD_LIST和RETURN_VALUE),LIST()的字节码有三条指令(LOAD_NAME、CALL_FUNCTION和RETURN_VALUE)。

    这些说明是什么意思?怎么理解他们?

    首先对于[],它是Python中的一组文字。与数字等文字量一样,它代表一个精确的固定值。

    也就是说,Python解析它的时候,知道它要表示一个列表,所以会直接调用解释器中的方法(对应BUILD_LIST)来创建一个列表,这样一步一个脚印。

    对于list(),“list”只是一个普通的名字,不是字面量,说明解释者一开始并不知道。

    所以解释器的第一步就是找到这个名字(对应LOAD_NAME)。它会按照一定的顺序(局部作用域-全局作用域-内置作用域)逐个搜索每个作用域,直到找到为止,如果没有找到,就会抛出NameError。

    解释器看到“list”后面有一对圆括号,所以第二步是把这个名字作为可调用对象调用,也就是把它作为函数调用(对应CALL_FUNCTION)。

    所以创建列表时,list()需要经过名称查找和函数调用两个步骤,才能真正开始创建列表(注意:CALL_FUNCTION在底层会有一些函数调用过程,这样才能达到与BUILD_LIST相同的逻辑,这里我们忽略)。

    至此,我们可以回答前面的问题:因为 list() 涉及的执行步骤更多,因此它比 [] 要慢一些。

    3 、list() 的速度提升

    看了前两个问题的回答过程,你可能会觉得不够好玩,可能会觉得即使知道了这些冷知识,也帮不了多少忙,看起来细微的改善也是微不足道的。

    但是我们Python猫生产的《Python 为什么》系列一直秉承着孜孜不倦的求知精神,这个问题是不可能不回答的。

    而且,由于发散思维的习惯,我还想到了另一个有趣的问题:list() 的速度能否提升呢?

    我前不久写了一篇文章就讨论这个问题,就是在新发布的Python 3.9.0版本中,对list()实现了更快的vectorcall协议,所以执行速度会有一定的提高。

    有兴趣的同学可以从Python官网下载3.9版。

    根据多轮测试结果,新版运行list()大约需要1秒,是[]运行时间的两倍。相比之前接近4倍的数据,现在的版本提升了不少。

    到目前为止,我们已经回答了一系列问题。如果觉得收获了什么,请赞美支持!欢迎大家以后关注更精彩的内容。

    本文属于“为什么Python”系列(Python猫出品),重点介绍Python的语法、设计和开发,试图以“为什么”问题为切入点展现Python的迷人魅力。所有文章都会在Github上存档。欢迎给小星星。项目地址: 网站链接

  • 0
  • 0
  • 0
  • 2
  • 请登录之后再进行评论

    登录
  • 单栏布局 侧栏位置: