In a previous tutorial we have seen how to use python code into c++ applications, today we are going to see the other side, how to use c++ code in a python application
Introduction: Python into C++
Performance improvements
Using C++ code into python
To be able to load and use c++ code into a python module we need to package it in a shared library. In Windows their name is Dynamic Link Library (DLL), to use this library in other platform we need to build a shared library with extension .so
When we create the project in Visual Studio we need to choose dynamic library in the project template list.
One thing that we need to change is the extension of our c++ library from .dll to .pyd. In Visual Studio we need to go to Project > Properties > Advanced > Target File Extension
In Windows, python will not able to import the library using other extension.
The project setup of includes and link paths needed to use pybind11 can be found in the previous tutorial embedding python into c++.
To define the python module that will be exported by the library we need to use the macro PYBIND11_MODULE(module_name, module_variable). Only one module can be defined in a .cpp file or library, the module_name must be equals to the name of the library.
For our example we will define a function to execute cosine calculate multiple times, an small example to compare the different time spent by python and c++ to execute the same code.
#include <math.h> #include <pybind11/pybind11.h> namespace py = pybind11; double icos(double num, int iterations) { double value = 0; for (int i = 0; i < iterations; ++i) { value = std::cos(num); } return value; } PYBIND11_MODULE(cppython3, m) { m.def("icos", &icos, "Calculates cosine multiple times"); }
To link our icos function in our module we need to define the function in the PYBIND11_MODULE macro and use the module_variable to link the python function name and a c++ function pointer, a short description can be added too at this point.
After Build the project we can find a .pyd binary in their output folder.
To be able to import our c++ module we need to put the .pyd file in the same path than the python script, or add their path folder to the python sys.path, or using PYTHONPATH environment variable.
import cppython3 cpp_res = cppython3.icos(18, 1000000)
Then just we need to import the library using their name and be access to the function using the module name as other python modules.
We can make a performance test to compare the time difference of our function between the python and c++ code.
from time import time from math import cos import cppython3 num = 18 iterations = 1000000 cpp_start = time() cpp_res = cppython3.icos(num, iterations) cpp_end = time() py_start = time() py_res = 0 for _ in range(iterations): py_res = cos(num) py_end = time() print(f" cpp time: {cpp_end-cpp_start}") print(f"python time: {py_end-py_start}") print(f" cpp result: {cpp_res}") print(f"python result: {py_res}")
The output shows us how the c++ module has better performance than the python version of the function, something expected by multiple reasons like memory management, internal pointer handlers for Global Interpreter Lock, lack of static typing…
We have seen how to make our python modules using c++ and how to import and use their functions later in our python scripts. An interesting way to obtain better performance in specific functions or full python modules!
You may also like:
Support this blog!
For the past year we have been dedicating more of our time to the creation of tutorials, mainly about game development. If you think these posts have either helped or inspired you, please consider supporting this blog. Thank you so much for your contribution!