从C++;矢量到Numpy ndarray非常慢 我使用Boost Python来计算程序的计算密集部分,它工作得很好,除了将数组从C++传递到Python,反之亦然,非常慢,这是程序整体效率的限制因素。
这里有一个例子来说明我的观点。在C++方面,我返回一个矩阵类型为<代码>向量> vector > <代码>的相对较大的大小。在Python端,我调用该函数,并尝试使用两种不同的方法:使用“代码”> NoMpy.Road < /C>方法,以及我自己(可能是非常天真的)C++实现了一个基本转换器。C++部分:从C++;矢量到Numpy ndarray非常慢 我使用Boost Python来计算程序的计算密集部分,它工作得很好,除了将数组从C++传递到Python,反之亦然,非常慢,这是程序整体效率的限制因素。,python,numpy,boost-python,Python,Numpy,Boost Python,这里有一个例子来说明我的观点。在C++方面,我返回一个矩阵类型为向量> vector > 的相对较大的大小。在Python端,我调用该函数,并尝试使用两种不同的方法:使用“代码”> NoMpy.Road < /C>方法,以及我自己(可能是非常天真的)C++实现了一个基本转换器。C++部分: #include <boost/python.hpp> #include <boost/python/numpy.hpp> #include <boost/python/suit
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
using namespace std;
typedef vector<double> vec;
typedef vector<vec> mat;
mat test()
{
int n = 1e4;
mat result(n, vec(n, 0.));
return result;
}
namespace p = boost::python;
namespace np = boost::python::numpy;
np::ndarray convert_to_numpy(mat const & input)
{
u_int n_rows = input.size();
u_int n_cols = input[0].size();
p::tuple shape = p::make_tuple(n_rows, n_cols);
np::dtype dtype = np::dtype::get_builtin<double>();
np::ndarray converted = np::zeros(shape, dtype);
for (u_int i = 0; i < n_rows; i++)
{
for (u_int j = 0; j < n_cols; j++)
{
converted[i][j] = input[i][j];
}
}
return converted;
}
BOOST_PYTHON_MODULE(hermite_cpp)
{
using namespace boost::python;
// Initialize numpy
Py_Initialize();
boost::python::numpy::initialize();
class_<vec>("double_vec")
.def(vector_indexing_suite<vec>())
;
class_<mat>("double_mat")
.def(vector_indexing_suite<mat>())
;
def("convert_to_numpy", convert_to_numpy);
def("test", test);
}
该计划的结果如下:
0.56
36.68
26.56
能否加快转换速度?或者,甚至更好的是,数组可以在NUMPY和C++之间共享。我在谷歌上搜索了很长一段时间,但没有取得多大成功。这只是一个部分答案,因为我不完全理解它工作的原因,但我发现重写转换函数
np::ndarray convert_to_numpy(mat const & input)
{
u_int n_rows = input.size();
u_int n_cols = input[0].size();
p::tuple shape = p::make_tuple(n_rows, n_cols);
p::tuple stride = p::make_tuple(sizeof(double));
np::dtype dtype = np::dtype::get_builtin<double>();
p::object own;
np::ndarray converted = np::zeros(shape, dtype);
for (u_int i = 0; i < n_rows; i++)
{
shape = p::make_tuple(n_cols);
converted[i] = np::from_data(input[i].data(), dtype, shape, stride, own);
}
return converted;
}
我一直以这种方式进行这些转换,它们执行得相当快:
void convert_to_numpy(const mat & input, p::object obj)
{
PyObject* pobj = obj.ptr();
Py_buffer pybuf;
PyObject_GetBuffer(pobj, &pybuf, PyBUF_SIMPLE);
void *buf = pybuf.buf;
double *p = (double*)buf;
Py_XDECREF(pobj);
u_int n_rows = input.size();
u_int n_cols = input[0].size();
for (u_int i = 0; i < n_rows; i++)
{
for (u_int j = 0; j < n_cols; j++)
{
p[i*n_cols+j] = input[i][j];
}
}
}
时间:
0.557882070541
0.12882900238
我使用vector.data()作为源,使用直接from_数据调用
vector<double>vertices;
auto np_verts= np::from_data(vertices.data(), // data ->
np::dtype::get_builtin<double>(), // dtype -> double
p::make_tuple(vertices.size()), // shape -> size
p::make_tuple(sizeof(double)), p::object()); // stride 1
矢量顶点;
自动np\u verts=np::from\u数据(顶点.数据(),//数据->
np::dtype::get_builtin(),//dtype->double
p::make_tuple(顶点.size()),//形状->大小
p::make_tuple(sizeof(double)),p::object();//步幅1
感谢您的输入!您知道如何将其调整为二维参数吗?请使用numpy.reformate
。
C = np.empty([10000*10000], dtype=np.float64)
timeit(test.convert_to_numpy)(A,C)
0.557882070541
0.12882900238
vector<double>vertices;
auto np_verts= np::from_data(vertices.data(), // data ->
np::dtype::get_builtin<double>(), // dtype -> double
p::make_tuple(vertices.size()), // shape -> size
p::make_tuple(sizeof(double)), p::object()); // stride 1