为什么是numpy';s cumsum比手动C++';s循环? 我试图理解为什么NUMPY的功能比手动的C++循环快得多。我使用pybind提供从C++代码到python的映射

为什么是numpy';s cumsum比手动C++';s循环? 我试图理解为什么NUMPY的功能比手动的C++循环快得多。我使用pybind提供从C++代码到python的映射,c++,numpy,pybind11,C++,Numpy,Pybind11,首先是数字: [24]中的[nav]:x=np.arange(100_000,dtype=np.float32) [25]中的[nav]:%timeit np.cumsum(x) 每个回路295µs±34.9µs(7次运行的平均值±标准偏差,每个1000个回路) [26]中的[ins]:%timeit-derived.cumsum(x) 每个回路9.26 ms±137µs(7次运行的平均±标准偏差,每个100个回路) 那么是如何导出的呢?cumsum(x)是如何获得的 模板 内联py::数组作

首先是数字:

[24]中的[nav]:x=np.arange(100_000,dtype=np.float32) [25]中的[nav]:%timeit np.cumsum(x) 每个回路295µs±34.9µs(7次运行的平均值±标准偏差,每个1000个回路) [26]中的[ins]:%timeit-derived.cumsum(x) 每个回路9.26 ms±137µs(7次运行的平均±标准偏差,每个100个回路) 那么
是如何导出的呢?cumsum(x)
是如何获得的

模板
内联py::数组作为pyarray(序列和序列){
自动大小=顺序大小();
自动数据=顺序数据();
自动顺序ptr=std::make_unique(std::move(seq));
auto capsule=py::capsule(seq_ptr.get(),[](void*p){
标准::唯一性(重新解释铸造(p));
});
序号ptr.release();
返回py::数组(大小、数据、胶囊);
}
标准::向量总和(常数标准::向量和nums){
向量结果(nums.size());
浮点数和=0;
对于(size_t i=0;i

<代码> ASypyRAMPARE/COMPUTE是从pyBIN问题中获得的,它保证了Python和C++之间的零拷贝。


<>注意,C++代码是用<代码> -O3-DNDUG-FPIC编译的。

< P>问题是在CUMUTHON的论证中。代码>常量std::vector&
仍在进行相当昂贵的复制。直接将
py::array\t
作为参数可以解决此问题


更多详细信息见:

此外,为循环的每个迭代计算
nums.size()
似乎效率低下。尝试在循环之前将其分配给
size\t
变量,并在测试中使用它。我对Python了解不多,所以不能说:Python是否使用单精度
float
数据?在C++中,在某些平台上,存储和读取这样的<代码>浮点数据比在代码>双< /代码>数据上的操作慢得多。这没有任何意义。一个手动的C++循环——老实说,也许这就是你的问题的答案。也许numpy版本的作者做的事情与手动循环不同,或者效率更高。它可能与所使用的语言无关。@SamVarshavchik当Python确定数组对象不可访问并对其进行GCs时,可能会调用lambda。然后在lambda期间销毁临时
std::unique_ptr
,并在
p
处释放
序列。它可能是用
delete-reinterpret\u-cast编写的(p),但代码来源的Github线程中的注释表示,编写此版本是为了避免显式的
新建
/
删除
(我认为这没什么用/应该在这里做…但无论如何)。