gpt4 book ai didi

python - 没有 numpy 临时对象?这是怎么做到的?

转载 作者:太空宇宙 更新时间:2023-11-03 16:49:57 25 4
gpt4 key购买 nike

我在 Cython 函数中运行以下代码:

a = np.zeros((3,3,))
b = np.ones((3,3,))

for i in range(1000000):
a += b * i

return a

在此代码中,只有两个 numpy 数组分配。我预计会有 1,000,002 个。当我用自己的类替换 numpy 数组时,我看到它的 __mul__ 函数被调用 1,000,000 次,导致 1,000,000 个对象分配。

numpy 如何知道它不需要在每次迭代时分配临时对象来存储 b * i?

最佳答案

如果你看看 cython 生成的代码,我认为关键是

__pyx_t_1 = PyNumber_Multiply(__pyx_v_b, __pyx_v_i); // some error checking follows

PyNumber_Multiplythe standard c-api function to call the multiplication operator因此没有理由相信它的行为方式与普通乘法调用不同。但是,我们可以轻松检查中间体的类型......我取出编译后的 C 文件并插入行

if (__Pyx_PrintOne(0, ((PyObject *)Py_TYPE(__pyx_t_1))) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

(这只是通过查看 print(type(a)) 生成的代码并更改变量名称而获得的。请注意,我没有更改 Python 代码,所以我不相信这会生成一个没有更改的变量'之前不存在)。然后我手动编译了该文件(Linux 上为 gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing \ -I/usr/include/python3.4m -o filename.so filename.c)。

这会打印

<class 'numpy.ndarray'>

这确实表明它已经生成了一个普通的 numpy 数组对象作为临时对象,正如您所期望的那样。没有什么神奇的事情发生。

<小时/>

作为一个有趣的旁注,我相信 Numba 的最新版本真正能够消除临时性,把整个操作真正做到位。然而,实际上证明您给出的示例可能会发生这种情况有点超出了我的范围(您可以通过在生成的函数上调用 inspect_asm() 来看到它,并注意到有很多加/乘指令,但不是明显的函数调用)。

关于python - 没有 numpy 临时对象?这是怎么做到的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35929202/

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