【发布时间】:2017-10-19 16:48:25
【问题描述】:
下面的例子似乎暗示了我不理解的运行时优化
谁能解释这种行为以及它如何适用于更一般的情况?
示例
考虑以下简单(示例)函数
def y(x): # str output
y = 1 if x else 0
return str(y)
def _y(x): # no str
y = 1 if x else 0
return y
假设我想将函数 y 应用于列表中的所有元素
l = range(1000) # test input data
结果
map 操作必须遍历列表中的所有元素。将函数拆分为双 map 明显优于单 map 函数,这似乎违反直觉
%timeit map(str, map(_y, l))
1000 loops, best of 3: 206 µs per loop
%timeit map(y, l)
1000 loops, best of 3: 241 µs per loop
更一般地说,这也适用于非标准库嵌套函数,例如
def f(x):
return _y(_y(x))
%timeit map(_y, map(_y, l))
1000 loops, best of 3: 235 µs per loop
%timeit map(f, l)
1000 loops, best of 3: 294 µs per loop
这是一个 python 开销问题,map 在可能的情况下编译低级 python 代码,因此在必须解释嵌套函数时受到限制?
【问题讨论】:
-
我刚刚使用 python 3.6 在我的机器上运行了你的示例。在这两个基准测试中,与双地图相比,单地图每个循环只需要大约一半的时间。你用的是哪个python版本?我的 timeit 输出每个循环大约需要 300 ns,这比您的版本快得多。你有一台 cpu / ram 受限的机器吗?
-
我们在几台机器上运行并使用 Python 2.7 得到了相同的结果。在 Python 3 上,我认为 map 以不同的方式评估?对 RAM 或 CPU 也没有限制
-
python 2 中的
map函数返回一个列表。在 python 3 中,它会产生结果,因此它们是动态评估的。这解释了不同的基准测试结果。 -
@pschill:在 Python 3 中创建
map()迭代器对象确实非常快,但不会进行任何迭代。在 Python 2 中,map()立即进行迭代并返回一个列表。如果您想在 Python 3 中进行测试,请在map()调用周围添加list()调用。
标签: python performance python-2.7 iteration nested-function