编程语言
首页 > 编程语言> > 使用 Pybind11 的 C++ 到 Python 模块

使用 Pybind11 的 C++ 到 Python 模块

作者:互联网

Python 永远是我的第一选择。但与 C/C++ 相比,它在速度、内存使用和能源消耗方面效率低下。当我开始使用暗网时,我开始了解 ctypes 库,它有助于在 python 中调用 c 函数。感觉很难将它用于 C++ 函数和类对象。我找到了一种使用 pybind11 实现此绑定的简单方法。
在这里我想展示如何使用 C++ 来提高我们使用 pybind11 的 python 项目的性能。我对堆排序算法进行了性能比较,结果包含在本文中。此外,我在这里解释了如何制作不透明类型,以防止 STL 数据类型(向量、地图等)和 Python 数据结构(列表、字典)之间的复制操作。

pybind11的安装

pybind11 的安装非常简单。Pybind11开发者推荐三种安装方式。我选择使用 pip 从 PyPI 安装。

pip 安装 pybind11

堆排序 C++

// cpp_sort.cpp 
# include  <pybind11/pybind11.h>
 # include  <pybind11/numpy.h>

 namespace py = pybind11; 
class  cpp_ { 
public : 
    int *a; 
    诠释n; 

cpp_ (py:: array_t < int > & arr){ // Numpy 数组模板
    auto buf = arr. 请求();// 请求缓冲区描述符
    a = ( int *)buf.ptr; 
    n = buf.shape[ 0 ]; 
} 
int  heapify ( int *a,int i, int n) {// 最大堆
    intleft_child=2*i+1; 
    intright_child= left_child+1; 
    最大整数=我;
    诠释吨; 
    if  (left_child < n) {if(a[left_child]>a[i]){max=left_child;}}
    else{return 0;}
   
    if(right_child < n && a[right_child]>a[max]){max =right_child;}
    if(max!=i){t=a[i]; a[i]=a[max];a[max]=t; heapify(a,max,n);}

    返回 0; 
}

 int 堆排序(){
    诠释我,吨;    
    for ( i= int (n/ 2 ) -1 ;i>= 0 ;i--){ 
        heapify (a,i,n);    
    } 
    // 一个一个地获取最大值
    for ( i=n -1 ;i>= 0 ;i--){ 
        t=a[ 0 ]; 
        a[ 0 ]=a[i];
        [i]=t; 
 
        堆化(a,0,i);
    }   
    返回 0 ; 
} 
}; 
PYBIND11_MODULE (cpp_sort,m ) { // cpp_sort 是模块名,m 是绑定接口  
    py:: class_ <cpp_>(m, "cpp_" ) // 将类作为 cpp_ 暴露给 python
def (py::init<py:: array_t < int > &>()) // 暴露类构造函数,数组作为输入
def ( "heapsort" , &cpp_::heapsort) // 从 cpp_ 类公开堆排序函数
def_readwrite ( "array_size" , &cpp_::n); //暴露变量n,重命名为array_size

 }

py::array_t 模板有助于将某些数据类型的 Numpy 数组传递到 C++ 端。应该包含 pybind11/numpy.h 标头以获得此功能。cpp_ 构造函数将 py::array_t 作为参数。要通过引用传递,数组的 dtype 应该匹配,即 np.int32 与 C++ 中的 int 相同,否则,更改不应反映在 python 端。
PYBIND11_MODULE 是一个带有两个参数的宏,cpp_sort 是模块名称,它应该不带引号,下一个参数是 m,它是用于接口绑定的 py::module_ 类型。
此代码写在 cpp_sort.cpp 文件中。可以使用下面创建共享对象库的命令在 Linux 中编译上述 C++。

C++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) cpp_sort.cpp -o cpp_sort$(python3-config --扩展后缀)$(python3 -m pybind11 --includes) cpp_sort.cpp -o cpp_sort $(python3-config --extension-后缀)

python中的堆排序

#py_sort.py 
class  py_ : 
  # 传递 numpy 数组的构造函数
  def  __init__ ( self,a ): 
    self.a=a 
    self.n=a.shape[ 0 ] 
  # 对于最大堆
  def  heapify ( self, n, i ): 
    maxx = i 
    left_child = 2 * i + 1 
     right_child = 2 * i + 2  
    if left_child < n and self.a[i] < self.a[left_child]: 
      maxx = left_child 
    if right_child < n and self.a[maxx] < self.a[right_child]:
      maxx= right_child 

    if maxx != i: 
      self.a[i],self.a[maxx] = self.a[maxx],self.a[i] 
      self.heapify( n, maxx) 

  def  heapsort ( self ): 
    # 逐一获取最大值
    for i in  range ( int (self.n/ 2 )- 1 , - 1 , - 1 ): 
      self.heapify( self.n, i) 
    
    for i in  range (self.n- 1 , 0 , - 1 ): 
      self.a[i], self.a[ 0 ] = self.a[ 0], self.a[i] 
      self.heapify(i, 0 )

标签:Pybind11,c++,Pytho,函数, STL,安装,数据,
来源: