Python两种获取可迭代对象长度的方法执行时间差异原因求解
问题根因:你的性能测试逻辑存在错误
你观察到的性能差异和两种写法本身的执行效率无关,完全是timeit工具的使用不当导致的结果失真:timeit的执行规则是:--setup参数定义的语句仅在测试开始前执行1次,后续你传入的测试语句会循环执行成千上万次。
第一种写法的测试逻辑错误点
你写的测试语句是x=list(x);len(x):
- 第一次循环执行时,
x还是setup中定义的range(1000)实例,执行x=list(x)后,x的指向被覆盖成了已经生成好的列表对象 - 从第二次循环开始,
list(x)的入参已经是现成的列表,而非惰性的range实例:把已有列表转成新列表的开销,远低于把惰性range生成完整列表的开销。你测的绝大多数循环都是低开销的列表转列表逻辑,结果自然更快。
第二种写法的测试是准确的
你写的测试语句是len(list(x)),全程没有修改x的指向,每次循环都是对初始的range(1000)做转换,得到的才是「把可迭代对象转列表再取长度」的真实耗时。
验证方法
你可以把第一种写法的测试语句修改为y=list(x);len(y),确保不会修改原始x的指向,再执行测试就会发现两种写法的耗时基本一致,和你贴的第二种测试结果几乎没有差异。
你之前看反汇编找不到差异是正常的:反汇编是把两种写法封装为函数的结果,函数里的it是每次调用都刷新的入参,不存在被覆盖的问题,两种写法本身的执行开销差异本来就可以忽略。
内容的提问来源于stack exchange,提问作者RobBlanchard
相关产品推荐
相关产品推荐

