从 C++ 调用 python 脚本而不每次都加载文件
Call python script from c++ without loading the file each time
我有一个 python 脚本,我需要调用很多次(大约 160000 次),而如果我尝试加载和调用硬 C++ 代码,我可以在不到一秒的时间内完成此操作python 脚本来执行此操作,可能需要几个小时!我 认为 如果我加载一次脚本,然后 运行 一遍又一遍地加载脚本,速度会明显加快。不幸的是,我不知道该怎么做。我不认为我可以使用 ifstream
加载文件,然后在字符串的所有行上使用 PyRun_SimpleString
。但是,如果速度不快,是否可以 return python 中的二维数组,然后将该数组转换为 std::vector
?
考虑以下函数,在名为 multiply.py
的文件中
#!/usr/bin/python3
def do_multiply(a, b):
c = 0
for i in range(0, a):
c += b
return c
在您的 C++ 文件中:
// Load the function
PyObject *pName = PyUnicode_FromString("multiply");
PyObject *pModule = PyImport_Import(pName);
PyObject *pFunction = PyObject_GetAttrString(pModule, "do_multiply")
假设你想调用这个函数3次,如下:
struct NumberPair
{
int x;
int y;
};
std::vector<NumberPair> numberPairs { {1, 2}, {5, 6}, {10, 12} };
然后,您可以简单地调用 PyObject_CallFunction
几次,同时加载模块:
for(const auto &numberPair : numberPairs)
{
PyObject *product = PyObject_CallFunction(pFunction, "ii", numberPair.x, numberPair.y);
if(product != NULL)
{
std::cout << "Product is " << PyLong_AsLong(product) << '\n';
Py_DECREF(product);
}
}
在调用 PyObject_CallFunction
之间不需要关闭模块,所以这应该不是问题。
我有一个 python 脚本,我需要调用很多次(大约 160000 次),而如果我尝试加载和调用硬 C++ 代码,我可以在不到一秒的时间内完成此操作python 脚本来执行此操作,可能需要几个小时!我 认为 如果我加载一次脚本,然后 运行 一遍又一遍地加载脚本,速度会明显加快。不幸的是,我不知道该怎么做。我不认为我可以使用 ifstream
加载文件,然后在字符串的所有行上使用 PyRun_SimpleString
。但是,如果速度不快,是否可以 return python 中的二维数组,然后将该数组转换为 std::vector
?
考虑以下函数,在名为 multiply.py
#!/usr/bin/python3
def do_multiply(a, b):
c = 0
for i in range(0, a):
c += b
return c
在您的 C++ 文件中:
// Load the function
PyObject *pName = PyUnicode_FromString("multiply");
PyObject *pModule = PyImport_Import(pName);
PyObject *pFunction = PyObject_GetAttrString(pModule, "do_multiply")
假设你想调用这个函数3次,如下:
struct NumberPair
{
int x;
int y;
};
std::vector<NumberPair> numberPairs { {1, 2}, {5, 6}, {10, 12} };
然后,您可以简单地调用 PyObject_CallFunction
几次,同时加载模块:
for(const auto &numberPair : numberPairs)
{
PyObject *product = PyObject_CallFunction(pFunction, "ii", numberPair.x, numberPair.y);
if(product != NULL)
{
std::cout << "Product is " << PyLong_AsLong(product) << '\n';
Py_DECREF(product);
}
}
在调用 PyObject_CallFunction
之间不需要关闭模块,所以这应该不是问题。