gpt4 book ai didi

python - 用 for 循环求和比用 reduce 求和更快?

转载 作者:太空狗 更新时间:2023-10-29 21:01:47 31 4
gpt4 key购买 nike

我想看看 reduce 比使用 for 循环进行简单的数值运算要快多少。这是我发现的(使用标准 timeit 库):

In [54]: print(setup)
from operator import add, iadd
r = range(100)

In [55]: print(stmt1)
c = 0
for i in r:
c+=i

In [56]: timeit(stmt1, setup)
Out[56]: 8.948904991149902
In [58]: print(stmt3)
reduce(add, r)

In [59]: timeit(stmt3, setup)
Out[59]: 13.316915035247803

再看一点:

In [68]: timeit("1+2", setup)
Out[68]: 0.04145693778991699

In [69]: timeit("add(1,2)", setup)
Out[69]: 0.22807812690734863

这是怎么回事?显然,reduce 确实比 for 循环得更快,但函数调用似乎占主导地位。 reduce 版本不应该几乎完全在 C 中运行吗?在 for 循环版本中使用 iadd(c,i) 使其运行时间约为 24 秒。为什么使用 operator.add 会比 + 慢那么多?我的印象是 + 和 operator.add 运行相同的 C 代码(我检查以确保 operator.add 不只是在 python 或其他任何东西中调用 +)。

顺便说一句,仅使用 sum 运行大约 2.3 秒。

In [70]: print(sys.version)
2.7.1 (r271:86882M, Nov 30 2010, 09:39:13)
[GCC 4.0.1 (Apple Inc. build 5494)]

最佳答案

reduce(add, r) 必须调用 add() 函数 100 次,因此函数调用的开销加起来 -- reduce 使用 PyEval_CallObject 在每次迭代时调用 add:

for (;;) {
...
if (result == NULL)
result = op2;
else {
# here it is creating a tuple to pass the previous result and the next
# value from range(100) into func add():
PyTuple_SetItem(args, 0, result);
PyTuple_SetItem(args, 1, op2);
if ((result = PyEval_CallObject(func, args)) == NULL)
goto Fail;
}

已更新:对评论中问题的回应。

当您在 Python 源代码中键入 1 + 2 时,字节码编译器会在适当的位置执行加法并将该表达式替换为 3:

f1 = lambda: 1 + 2
c1 = byteplay.Code.from_code(f1.func_code)
print c1.code

1 1 LOAD_CONST 3
2 RETURN_VALUE

如果添加两个变量a + b,编译器将生成加载两个变量并执行 BINARY_ADD 的字节码,这比调用函数执行加法要快得多:

f2 = lambda a, b: a + b
c2 = byteplay.Code.from_code(f2.func_code)
print c2.code

1 1 LOAD_FAST a
2 LOAD_FAST b
3 BINARY_ADD
4 RETURN_VALUE

关于python - 用 for 循环求和比用 reduce 求和更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5436503/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com