如何使用 C++ 的字节码优化来初始化嵌入式 Python 解释器?
How can I initialize an embedded Python interpreter with bytecode optimization from C++?
我正在 运行在我的 C++ 项目中安装一个嵌入式 Python 2.7 解释器,我想尽可能地优化解释器。我想要执行此操作的一种方法是使用 __debug__
变量禁用我的调试语句。由于 运行ning Python 字节码优化(即 -O
标志),我还想实现任何可能的性能提升。
This Stack Overflow question 解决了 __debug__
变量的使用问题,并指出可以通过 运行 宁 Python 和 -O
来关闭它。但是,对于使用 C++ hooks 创建的嵌入式解释器,显然不能传递此标志。
下面是我的嵌入式解释器初始化代码。该代码并不意味着 运行 是孤立的,但应该提供对我正在使用的环境的一瞥。有什么方法可以更改或添加到这些函数调用以指定嵌入式解释器应应用字节码优化,将 __debug__
变量设置为 False
,并且通常 运行 in "release" 模式而不是 "debug" 模式?
void PythonInterface::GlobalInit() {
if(GLOBAL_INITIALIZED) return;
PY_MUTEX.lock();
const char *chome = getenv("NAO_HOME");
const char *cuser = getenv("USER");
string home = chome ? chome : "", user = cuser ? cuser : "";
if(user == "nao") {
std::string scriptPath = "/home/nao/python:";
std::string swigPath = SWIG_MODULE_DIR ":";
std::string corePath = "/usr/lib/python2.7:";
std::string modulePath = "/lib/python2.7";
setenv("PYTHONPATH", (scriptPath + swigPath + corePath + modulePath).c_str(), 1);
setenv("PYTHONHOME", "/usr", 1);
} else {
std::string scriptPath = home + "/core/python:";
std::string swigPath = SWIG_MODULE_DIR;
setenv("PYTHONPATH", (scriptPath + swigPath).c_str(), 1);
}
printf("Starting initialization of Python version %s\n", Py_GetVersion());
Py_InitializeEx(0); // InitializeEx(0) turns off signal hooks so ctrl c still works
GLOBAL_INITIALIZED = true;
PY_MUTEX.unlock();
}
void PythonInterface::Init(VisionCore* core) {
GlobalInit();
PY_MUTEX.lock();
CORE_MUTEX.lock();
CORE_INSTANCE = core;
thread_ = Py_NewInterpreter();
PyRun_SimpleString(
"import pythonswig_module\n"
"pythonC = pythonswig_module.PythonInterface().CORE_INSTANCE.interpreter_\n"
"pythonC.is_ok_ = False\n"
"from init import *\n"
"init()\n"
"pythonC.is_ok_ = True\n"
);
CORE_MUTEX.unlock();
PY_MUTEX.unlock();
}
我通过在调用 Py_InitializeEx(0)
之前设置 PYTHONOPTIMIZE
环境变量解决了这个问题:
/* ... snip ... */
setenv("PYTHONOPTIMIZE", "yes", 0);
printf("Starting initialization of Python version %s\n", Py_GetVersion());
Py_InitializeEx(0); // InitializeEx(0) turns off signal hooks so ctrl c still works
/* ... snip ... */
我正在 运行在我的 C++ 项目中安装一个嵌入式 Python 2.7 解释器,我想尽可能地优化解释器。我想要执行此操作的一种方法是使用 __debug__
变量禁用我的调试语句。由于 运行ning Python 字节码优化(即 -O
标志),我还想实现任何可能的性能提升。
This Stack Overflow question 解决了 __debug__
变量的使用问题,并指出可以通过 运行 宁 Python 和 -O
来关闭它。但是,对于使用 C++ hooks 创建的嵌入式解释器,显然不能传递此标志。
下面是我的嵌入式解释器初始化代码。该代码并不意味着 运行 是孤立的,但应该提供对我正在使用的环境的一瞥。有什么方法可以更改或添加到这些函数调用以指定嵌入式解释器应应用字节码优化,将 __debug__
变量设置为 False
,并且通常 运行 in "release" 模式而不是 "debug" 模式?
void PythonInterface::GlobalInit() {
if(GLOBAL_INITIALIZED) return;
PY_MUTEX.lock();
const char *chome = getenv("NAO_HOME");
const char *cuser = getenv("USER");
string home = chome ? chome : "", user = cuser ? cuser : "";
if(user == "nao") {
std::string scriptPath = "/home/nao/python:";
std::string swigPath = SWIG_MODULE_DIR ":";
std::string corePath = "/usr/lib/python2.7:";
std::string modulePath = "/lib/python2.7";
setenv("PYTHONPATH", (scriptPath + swigPath + corePath + modulePath).c_str(), 1);
setenv("PYTHONHOME", "/usr", 1);
} else {
std::string scriptPath = home + "/core/python:";
std::string swigPath = SWIG_MODULE_DIR;
setenv("PYTHONPATH", (scriptPath + swigPath).c_str(), 1);
}
printf("Starting initialization of Python version %s\n", Py_GetVersion());
Py_InitializeEx(0); // InitializeEx(0) turns off signal hooks so ctrl c still works
GLOBAL_INITIALIZED = true;
PY_MUTEX.unlock();
}
void PythonInterface::Init(VisionCore* core) {
GlobalInit();
PY_MUTEX.lock();
CORE_MUTEX.lock();
CORE_INSTANCE = core;
thread_ = Py_NewInterpreter();
PyRun_SimpleString(
"import pythonswig_module\n"
"pythonC = pythonswig_module.PythonInterface().CORE_INSTANCE.interpreter_\n"
"pythonC.is_ok_ = False\n"
"from init import *\n"
"init()\n"
"pythonC.is_ok_ = True\n"
);
CORE_MUTEX.unlock();
PY_MUTEX.unlock();
}
我通过在调用 Py_InitializeEx(0)
之前设置 PYTHONOPTIMIZE
环境变量解决了这个问题:
/* ... snip ... */
setenv("PYTHONOPTIMIZE", "yes", 0);
printf("Starting initialization of Python version %s\n", Py_GetVersion());
Py_InitializeEx(0); // InitializeEx(0) turns off signal hooks so ctrl c still works
/* ... snip ... */