从C++;矢量到Numpy ndarray非常慢 我使用Boost Python来计算程序的计算密集部分,它工作得很好,除了将数组从C++传递到Python,反之亦然,非常慢,这是程序整体效率的限制因素。

从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

这里有一个例子来说明我的观点。在C++方面,我返回一个矩阵类型为<代码>向量> vector > <代码>的相对较大的大小。在Python端,我调用该函数,并尝试使用两种不同的方法:使用“代码”> NoMpy.Road < /C>方法,以及我自己(可能是非常天真的)C++实现了一个基本转换器。C++部分:

#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