【问题标题】:Time difference between two alike methods to get length of iterable获得可迭代长度的两种相似方法之间的时间差
【发布时间】:2021-11-27 12:34:53
【问题描述】:

我想出了一些很奇怪的东西。目标是评估可迭代对象的长度。

python -m timeit --setup="x = range(1000)" "x=list(x);len(x)"

1000000 次循环,3 次中的最佳:每个循环 1.82 微秒

python -m timeit --setup="x = range(1000)" "len(list(x))"

100000 次循环,3 次中的最佳:每个循环 9.92 微秒

谁能解释第一种方法更快的原因?

我试图查看汇编指令,但它无助于理解这种行为。

与:x=list(x);len(x)

>>> dis.dis(meth1)
  2           0 LOAD_GLOBAL              0 (list)
              2 LOAD_FAST                0 (it)
              4 CALL_FUNCTION            1
              6 STORE_FAST               1 (x)

  3           8 LOAD_GLOBAL              1 (len)
             10 LOAD_FAST                1 (x)
             12 CALL_FUNCTION            1
             14 RETURN_VALUE

len(list(x)):

>>> dis.dis(meth2)
  2           0 LOAD_GLOBAL              0 (len)
              2 LOAD_GLOBAL              1 (list)
              4 LOAD_FAST                0 (it)
              6 CALL_FUNCTION            1
              8 CALL_FUNCTION            1
             10 RETURN_VALUE

【问题讨论】:

  • 如果这个问题真的是“为什么 meth2 更快”,那么标题不应该是“最快的方式”。如果问题是“最快的方式”,@MartesBerkeley 的答案是正确的,但无需担心为什么更快。在任何情况下,问题或标题都需要编辑
  • 你说得对,我修改了标题

标签: python performance


【解决方案1】:

您必须考虑 setup 只执行一次这一事实。

测试

--setup="x = range(1000)" "x=list(x);len(x)"

range 转换为 list 并将其存储回x。下一次迭代,它已经是一个列表,所以没有什么可做的了。

如果您将其更改为不同的变量名称,则差异应该消失:

--setup="x = range(1000)" "something=list(x);len(something)"

在其他测试中

--setup="x = range(1000)" "len(list(x))"

x 仍然是一个范围,需要转换成一个列表 100000 次。

【讨论】:

  • 你是对的!谢谢!
猜你喜欢
  • 2021-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
相关资源
最近更新 更多