c比python快多少倍_python和c++哪个简单

c比python快多少倍_python和c++哪个简单国外有测试指出在相同复杂度算法中,C++约比Python快50倍左右。因此Python适合上层应用;C++则适合底层控制。本文介绍如何让C++和Python形成优势互补

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

1 为什么需要多语言联合编程?

在这里插入图片描述
在大型工程项目中,经常会遇到多语言联合编程的情况,举个例子:

在一个远端控制系统中,前端Web使用html+css+js;后端采用python-flask作为服务端,底层控制采用C/C++

这是因为不同编程语言有各自的适用场景和语法特性,联合编程可使得各种语言发挥自己的特长。本文主要比较Python和C++,先列举各自特点如下:

对比项目 C++ Python
本质 编译型语言 解释型语言
编程难度 难以掌握 易于上手
语法特性 静态 动态
垃圾回收 不支持 支持
安装 难(需要专门打包)
数据类型 在编译时由关键字确定 在运行时由数值确定
函数 输入参数和返回值类型有限制 输入参数和返回值类型无限制
执行速度
性能

国外有一个测试指出在相同复杂度算法中,C++约比Python快50倍左右。因此Python不适合用于底层算法的开发,应用在上层应用中作粘合剂或进行智能领域的研究比较占优;C/C++则适合用于底层控制算法编程。下面主要介绍Python调用C++,让C++和Python形成优势互补。

2 Python调用C++的主要方式

主要介绍三种C++/Python联合编程的方式:

2.1 SWIG

  • 支持Python、Java、Ruby等语言调用C接口
  • 文档全面,易于学习
  • 绑定性能欠佳, 不支持属性和内部类封装
  • C++支持不好

2.2 Boost::Python

  • 支持Python2与Python3调用C++接口
  • 大量使用C++ templates,明显提高编译时间
  • 非常可靠、稳定、经过充分测试
  • 语法较复杂,且文档不详细

    在这里插入图片描述

本文采用Boost::Python进行C++/Python联合编程。

2.3 ctypes

  • 灵活,完全兼容C语言
  • 使用较繁琐且不支持C++特性

3 Boost::Python安装

打开参考中的官方下载地址,根据不同的操作系统平台下载boost,UNIX和Windows的安装流程差不多,下面以Windows系统为例说明安装过程。

在这里插入图片描述
按下面步骤安装编译Boost::Python

  • 下载最新的boost_1_79_0.zip并解压到本地目录
  • 运行bootstrap.bat在目录下产生b2.exe可执行文件
  • 进入根目录新建user-config.jam用户配置文件,存放本地C++/Python信息
    using msvc : 14.2;
    using python : 3.7.5
    	: "D:/Anaconda/Anaconda/envs/test/python.exe"
    	: "D:/Anaconda/Anaconda/envs/test/include"
    	: "D:/Anaconda/Anaconda/envs/test/libs";
    

    其中msvcVisual Studio对应的msvc toolset版本,具体对应关系如下:在这里插入图片描述
    python则定义了本地使用的python解释器相关路径和库

  • 命令行执行自动化安装:
    b2 --with-python install --prefix="D:/3rdLib/boost/boost_1_79_0/bin/lib64-msvc-14.2" toolset=msvc-14.2 link=static address-model=64 --user-config=user-config.jam

    其中一些关键参数解释如下:

    • with- | without-:前者后接要编译的Boost库名,如本文中只需编译Boost下的Python库;后者即为编译除之外的所有库,缺省则为全部编译
    • stage | install:前者表示只生成库文件(.dll与.lib),后者会额外生成include目录包含库文件对应的头文件,推荐使用stage,因为安装完成后根目录下的boost与include目录文件完全一致,可直接作为头文件使用,节省编译时间
    • stagedir | prefix:表示编译生成文件的路径,前者对应stage安装模式,后者对应install安装模式。建议在根目录下新建bin目录管理生成的库文件
      # VS2019编译的x86库文件
      bin/lib32-msvc-14.2 
      # VS2019编译的x64库文件
      bin/lib64-msvc-14.2
      
    • toolset:表示编译器,可选gccmsvc-14.2(VS2019)等
    • link:指定生成动态链接库shared还是静态链接库static,推荐使用静态库方式编译,这样发布程序时无需连带发布Boost的.dll文件,本文采用静态编译。
      在这里插入图片描述
      在这里插入图片描述
    • address-model:指定编译版本,可选32 | 64,该参数必须和本地安装的Python位数相对应,否则会编译出错
    • user-config:使用的本地用户配置文件路径

补充一下编译库文件的命名格式:

libboost_python37-vc142-mt-gd-x64-1_79
| ||   | |      | |   | || ||| | | |  |
 -  ---   ------   ---  -- - -  -   --
 1   2       3      4    5 6 7  8    9
  1. 静态库以lib开头,动态库没有lib前缀
  2. boost::python库名称和版本
  3. 编译器名称及版本
  4. mt代表threading=multi,没有则代表threading=single
  5. s代表runtime-link=static,没有则代表runtime-link=shared
  6. gd代表debug版本,没有则代表release版本
  7. x32代表32 位程序,x64代表64 位
  8. Boost库版本,1_79代表Boost 1.79版本。

4 测试实例:python继承C++接口

新建工程文件夹,包含三个文件helloworld.cpphelloworld.pyCMakeLists.txt

helloworld.cpp中编写:

// 因为采用静态编译boost库,因此必须定义此宏,否则编译出错
#define BOOST_PYTHON_STATIC_LIB

#include<boost/python.hpp>
#include<boost/python/wrapper.hpp>
#include<string>
#include<iostream>

using namespace boost::python;
using namespace std;

struct Base
{ 
   
    virtual ~Base() { 
   }
    virtual int f() { 
    return 0; };
};

struct BaseWrap : Base, wrapper<Base>
{ 
   
    int f()
    { 
   
        if (override f = this->get_override("f"))
            return f(); //如果函数进行重载了,则返回重载
        return Base::f(); //否则返回基类
    }
    int default_f() { 
    return this->Base::f(); }
};

BOOST_PYTHON_MODULE(hello)
{ 
   
    class_<BaseWrap, boost::noncopyable>("Base")
        .def("f", &Base::f, &BaseWrap::default_f);
}

CMakeLists.txt中编写编译规则

project(Boost_Test)
cmake_minimum_required(VERSION 2.8.3)

if(MSVC)
    # set(Boost_USE_STATIC_LIBS ON)
    set(Boost_DIR D:/3rdLib/boost/boost_1_79_0/stage/lib/cmake/Boost-1.79.0)
    set(PYTHON_INCLUDE_DIRS D:/Anaconda/Anaconda/envs/test/include)
    set(PYTHON_LIBRARIES D:/Anaconda/Anaconda/envs/test/libs/python37.lib)
    find_package(Boost 1.79.0 CONFIG COMPONENTS python REQUIRED)
    include_directories(${Boost_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS})
endif(MSVC)

set(MODULE_NAME hello)
add_library(${MODULE_NAME} SHARED
    helloword.cpp
	)

if (UNIX)
  set_target_properties(${MODULE_NAME}
    PROPERTIES
    PREFIX ""
  )
elseif (WIN32)
  set_target_properties(${MODULE_NAME}
  PROPERTIES
  SUFFIX ".pyd"
  )
endif()

target_link_libraries(${MODULE_NAME}
  ${Boost_LIBRARIES}
  ${PYTHON_LIBRARIES}
)

在工程目录下执行以下命令行:

mkdir build
cd build
cmake ..
make

即可编译出hello.pyd二进制文件,将该文件置于工程目录下(与helloworld.py在同一个目录),在helloworld.py中导入接口,测试多态:

import hello 
base = hello.Base()
# 定义派生类,继承C++类
class Derived(hello.Base):
    def f(self):
        return 42

derived = Derived()
print( base.f())
print (derived.f())

输出以下内容,证明实验成功

>>> 0
>>> 42

5 常见问题

  1. #include <boost\python.hpp>无法打开源文件'pyconfig.h'

    解决方案:首先确保当前虚拟环境下有pyconfig,否则需要pip install。接着对于vscode,在c_cpp_properties.json中添加python的include目录

  2. error LNK2019: 无法解析的外部符号 "__declspec(dllimport) class boost::python::xxx

    解决方案:库链接出错,对于静态编译的Boost::python库需要在C++文件中声明静态编译宏

    #define BOOST_PYTHON_STATIC_LIB
    

6 参考文档


? 更多精彩专栏



?源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/185745.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 如何生成Android的keystore文件

    如何生成Android的keystore文件

    2021年10月1日
    50
  • spring循环依赖为什么不是二级缓存_有效循环血量不依赖

    spring循环依赖为什么不是二级缓存_有效循环血量不依赖前置知识:所谓的三级缓存只是三个可以当作是全局变量的Map,Spring的源码中大量使用了这种先将数据放入容器中等使用结束再销毁的代码风格Spring的初始化过程大致有四步我们说的循环依赖就是第四步在给Bean属性注入的时候发生的一个问题循环依赖就是:假设有两个类A和B,A中需要注入B,B中需要注入A由于A注入B时B没有创建,B创建时A也无法创建导致的死循环问题我们都知道AOP是Spring的一个重要核心思想,其实现就是根据动态代理来实现的,也就是说我们的Bean其实很大概率都是要生成代理类,让

    2025年7月13日
    0
  • Java实现冒泡排序(详解)[通俗易懂]

    Java实现冒泡排序(详解)[通俗易懂]深度解析冒泡排序算法publicclassMySort{publicstaticvoidbubbleSort(intarray[]){for(inti=0;i<array.length;i++){for(intj=0;j<array.length-1-i;j++){if(array[j]>array[j+1]){

    2022年6月21日
    20
  • 谈谈.Net技术面试【转】

    谈谈.Net技术面试【转】

    2021年8月15日
    47
  • 天翼云负载均衡配置ssl证书_阿里云服务器证书

    天翼云负载均衡配置ssl证书_阿里云服务器证书1、购买证书(图片有误,应该是购买通配符证书):2、申请证书:填写证书绑定域名:*.tianya.com联系人信息:xxx在自己的域名管理平台配置txt记录值,通过dns的txt记录类型来验证信息3、证书验证(根据上图中的DNS记录类型在域名管理平台进行txt记录验证,验证通过后点击上图中的验证按钮后会提示验证通过)4、申请验证完成:4.1点击验证后返回ssl证书管理平台页面会显示申请审核中4.2审核通过后下载自己需要的相应的证书备注:使用阿里云负载均衡进行https访问网站,

    2022年9月26日
    0
  • 史上最全Java多线程面试题及答案[通俗易懂]

    史上最全Java多线程面试题及答案[通俗易懂]这篇文章主要是对多线程的问题进行总结的,因此罗列了40个多线程的问题。这些多线程的问题,有些来源于各大网站、有些来源于自己的思考。可能有些问题网上有、可能有些问题对应的答案也有、也可能有些各位网友也都看过,但是本文写作的重心就是所有的问题都会按照自己的理解回答一遍,不会去看网上的答案,因此可能有些问题讲的不对,能指正的希望大家不吝指教。 1、多线程有什么用?一个可能在很多人看来…

    2022年8月27日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号