我编写了一个小类方法,通过boost::python
从C ++调用python函数,我已经观察到纯python的速度提升:
namespace bp = boost::python;
double pyf::eval(double * const x) const
{
bp::list lx;
for (size_t i = 0; i < this->get_n(); i++)
lx.append(x[i]);
return bp::call<double>(pycb_, lx);
}
pycb_
是我的PyObject*
回调函数。
我的问题是:您是否知道从boost::python::list
指针创建double *
的更智能方法?
我目前的解决方案非常虚拟,但我发现boost::python
文档很难理解,缺乏具体的例子,所以欢迎您的体验!
有关信息,我使用的是较旧版本的Boost(1.41)。此外,我的其余部分依赖于boost
,我宁愿坚持boost::python
并避免添加第三方pkgs。
答案 0 :(得分:0)
据我所知,迭代是从这种类型的源填充Boost.Python list
的唯一方法。替代迭代解决方案删除一些样板代码包括使用Boost.ForEach或std::for_each
算法。
例如,以下两个代码段与原始代码等效:
double pyf::eval(double * const x) const
{
bp::list lx;
BOOST_FOREACH(double& value, boost::make_iterator_range(x, x + this->get_n()))
lx.append(value);
return bp::call<double>(pycb_, lx);
}
和
double pyf::eval(double * const x) const
{
bp::list lx;
std::for_each(x, x + this->get_n(),
boost::bind(&bp::list::append<double>, &lx, _1));
return bp::call<double>(pycb_, lx);
}
这是一个嵌入式Python的基本示例,显示了两种方法:
#include <algorithm>
#include <iostream>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/python.hpp>
int main()
{
Py_Initialize();
namespace python = boost::python;
try
{
python::object main = python::import("__main__");
// Add the verbose_sum function to main.
python::exec(
"def verbose_sum(x):\n"
" print x\n"
" return sum(x)\n"
"\n", main.attr("__dict__"));
// Mockup data.
PyObject* callback = python::object(main.attr("verbose_sum")).ptr();
boost::array<double, 5> x_array = {{ 1, 2, 3, 4, 5 }};
double* const x = &x_array[0];
const std::size_t n = x_array.size();
// Range iterator.
{
python::list x_list;
BOOST_FOREACH(double& value, boost::make_iterator_range(x, x + n))
x_list.append(value);
std::cout << python::call<double>(callback, x_list) << std::endl;
}
// Algorithm with binding.
{
python::list x_list;
std::for_each(x, x + n,
boost::bind(&python::list::append<double>, &x_list, _1));
std::cout << python::call<double>(callback, x_list) << std::endl;
}
}
catch (python::error_already_set&)
{
PyErr_Print();
}
}
输出:
[1.0, 2.0, 3.0, 4.0, 5.0]
15
[1.0, 2.0, 3.0, 4.0, 5.0]
15