Я использую Boost python для вычислительных частей программы, и он работает довольно хорошо, за исключением того, что передача массивов из C ++ в python и наоборот очень медленная, до такой степени, что это ограничивающий фактор для общей эффективности программы.
Вот пример, иллюстрирующий мою точку зрения. На стороне C ++ я возвращаю матрицу с типом vector< vector<double> >
относительно большого размера. Со стороны Python я вызываю эту функцию и пытаюсь преобразовать полученный массив, используя два разных метода: метод numpy.array
и мою собственную (вероятно, довольно наивную) реализацию 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);
}
Python часть:
import test
import numpy as np
import time
def timeit(function):
def wrapper(*args, **kwargs):
tb = time.time()
result = function(*args, **kwargs)
te = time.time()
print(te - tb)
return result
return wrapper
A = timeit(test.test)()
B = timeit(np.array)(A)
C = timeit(test.convert_to_numpy)(A)
Результаты этой программы следующие:
0.56
36.68
26.56
Может ли преобразование быть сделано быстрее? Или, что еще лучше, массив может быть разделен между Numpy и C ++. Я долго гуглил, но без особого успеха.