【问题标题】:Speedups in Looping Structures循环结构中的加速
【发布时间】:2013-12-07 16:36:16
【问题描述】:

在以不同方式构建列表时,我注意到一些有趣的行为。 .append 比 list-comprehensions 需要更长的时间,list-comprehensions 比map 需要更长的时间,如下实验所示:

def square(x): return x**2

def appendtime(times=10**6):
  answer = []
  start = time.clock()
  for i in range(times):
    answer.append(square(i))
  end = time.clock()
  return end-start

def comptime(times=10**6):
  start = time.clock()
  answer = [square(i) for i in range(times)]
  end = time.clock()
  return end-start

def maptime(times=10**6):
  start = time.clock()
  answer = map(square, range(times))
  end = time.clock()
  return end-start

for func in [appendtime, comptime, maptime]:
  print("%s: %s" %(func.__name__, func()))

Python 2.7:

appendtime: 0.42632
comptime: 0.312877
maptime: 0.232474

Python 3.3.3:

appendtime: 0.614167
comptime: 0.5506650000000001
maptime: 0.57115

现在,我很清楚 python 2.7 中的range 构建了一个列表,所以我明白了为什么 python 2.7 和 3.3 中相应函数的时间之间存在差异。我比较关心的是append、list-comprehension和map之间的相对时差。

起初,我认为这可能是因为map 和列表推导可以为解释器提供结果列表的最终大小的知识,这将允许解释器在后台 malloc 一个足够大的 C 数组来存储名单。按照这种逻辑,list-comprehensions 和 map 应该花费几乎相同的时间。
但是,时序数据显示,在 python 2.7 中,listcomps 的速度是 append 的 ~1.36 倍,map 的速度是 listcomps 的 ~1.34 倍。
更奇怪的是,在 python 3.3 中,listcomps 的速度大约是 append 的 1.12 倍,而 map 实际上比 listcomps 慢。

显然,map 和 listcomps 不会“按照相同的规则玩”;显然,map 利用了 listcomps 没有的东西。
有人能解释一下这些时间值差异背后的原因吗?

【问题讨论】:

  • 强制 "你为什么不使用timeit?它对于基准测试要好得多。"评论。
  • @delnan -- 我也在想这个:)

标签: python performance list python-2.7 python-3.x


【解决方案1】:

首先,在 python3.x 中,map 返回一个 iterable,而不是一个列表,这样就解释了那里的 50kx 加速。为了让它成为一个公平的时机,在 python3.x 中你需要list(map(...))

其次,.append 会变慢,因为每次循环时,解释器都需要查找列表,然后需要查找列表中的append 函数。这种额外的.append 查找不需要在list-comp 或map 中进行。

最后,通过列表理解,我相信函数square 需要在循环的每一轮中查找。使用 map 时,只有在您调用 map 时才会查​​找它,这就是为什么如果您在列表理解中调用函数,map 通常会更快。请注意,列表理解通常通过 lambda 函数击败 map

【讨论】:

  • @inspectorG4dget -- 是的,我添加了更多内容来解释这种差异。
  • 我已经用list(map(...)) 更新了我的帖子,这似乎更慢了。你能解决这个问题吗?
  • @inspectorG4dget -- 不确定我可以。这可能是因为在这种情况下,您实际上需要调用map(...).__iter__,然后调用__next__ 函数很多次(您没有使用list-comp)。无论如何,您的差异只有约 5%,这是非常小的。
猜你喜欢
  • 2019-01-29
  • 2014-06-06
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2019-05-15
  • 2021-09-03
  • 1970-01-01
相关资源
最近更新 更多