首页 > 解决方案 > `built-in method numpy.core._multiarray_umath.implement_array_function` 是性能瓶颈吗?

问题描述

numpy v1.18.2在一些模拟中使用,并使用内置函数,例如np.unique,np.diffnp.interp. 我在标准对象上使用这些函数,即列表或 numpy 数组。

当我检查时cProfile,我看到这些函数调用了一个内置方法numpy.core._multiarray_umath.implement_array_function,并且这个方法占了32.5%我的运行时!据我了解,这是一个包装器,它执行一些检查以确保传递给函数的参数与函数兼容。

我有两个问题:

  1. 这个函数 ( implement_array_function) 实际上占用了这么多时间,还是实际上我正在执行的操作 ( np.unique, np.diff, np.interp) 实际上占用了所有这些时间?也就是说,我是否误解了 cProfile 输出?我对snakeviz 的分层输出感到困惑。请在此处查看snakeviz 输出,并在此处查看该功能的详细信息。
  2. 有什么方法可以禁用/绕过它,因为每次都不需要检查输入,因为我传递给这些 numpy 函数的参数已经在我的代码中进行了控制?我希望这会给我带来性能上的提升。

我已经看到了这个问题(什么是 numpy.core._multiarray_umath.implement_array_function 以及为什么要花费大量时间?),但我无法理解该函数到底是什么或做什么。我也试图理解NEP 18,但无法弄清楚如何准确解决这个问题。请补充我的知识空白并纠正任何误解。如果有人能像我 5 岁(r/explainlikeimfive/)一样向我解释这一点,而不是假设 Python 的开发人员级别的知识,我也将不胜感激。

标签: pythonpython-3.xnumpyscipysnakeviz

解决方案


以下所有信息均取自NEP 18

这个函数 ( implement_array_function) 实际上占用了这么多时间,还是实际上我正在执行的操作 ( np.unique, np.diff, np.interp) 实际上占用了所有这些时间?

正如@hpaulj 在评论中正确提到的那样,调度程序的开销为每个 numpy 函数调用增加了 2-3 微秒。一旦在 C 中实现,这可能会缩短到 0.5-1 微秒。请参见此处

有什么方法可以禁用它/绕过它

是的,从 NumPy 1.17 开始,您可以将环境变量设置 NUMPY_EXPERIMENTAL_ARRAY_FUNCTION为 0(在导入 numpy 之前),这将禁用implement_array_function(参见此处)。就像是

import os
os.environ['NUMPY_EXPERIMENTAL_ARRAY_FUNCTION'] = '0'
import numpy as np

但是,禁用它可能不会给您带来任何显着的性能改进,因为它的开销只有几微秒,这也是以后 numpy 版本中的默认设置。


推荐阅读