3

I am running an embedded Python 2.7 interpreter within my C++ project, and I would like to optimize the interpreter as much as possible. One way I would like to do this is by disabling my debug statements using the __debug__ variable. I would also like to realize any possible gains in performance due to running Python with bytecode optimizations (i.e. the -O flag).

This Stack Overflow question addresses the use of the __debug__ variable, and notes that it can be turned off by running Python with -O. However, this flag can obviously not be passed for an embedded interpreter that is created with C++ hooks.

Below is my embedded interpreter initialization code. The code is not meant to be run in isolation, but should provide a glimpse into the environment I'm using. Is there some way I can alter or add to these function calls to specify that the embedded interpreter should apply bytecode optimizations, set the __debug__ variable to False, and in general run in "release" mode rather than "debug" mode?

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();
}
Community
  • 1
  • 1
Jake
  • 7,565
  • 6
  • 55
  • 68

1 Answers1

1

I solved this by setting the PYTHONOPTIMIZE environment variable prior to calling Py_InitializeEx(0):

/* ... 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 ... */
Jake
  • 7,565
  • 6
  • 55
  • 68