前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 搭配 C++ 让性能直接拉满

Python 搭配 C++ 让性能直接拉满

作者头像
初代庄主
发布2023-02-20 10:52:22
5610
发布2023-02-20 10:52:22
举报
文章被收录于专栏:初代庄主

背景

本人的主力语言是 Python & JavaScript & C++;数据采集主要用 JavaScript 语言实现,后面的分析用 Python 实现。

经验上看 Python 可以解决掉我 99.9% 的问题,之所不敢说是 100%,是因为有一次我把一小部分代码用 C++ 重写后整体耗时下降 40 倍。这个也就是我后来开始重视 C++ 的原因。

前段时间 TOIBE 2022 年编程语言排名发布了, C++ 成为了 2022 年的最佳编程语言;我的第一感觉就是 “这家伙理所应当呀!”

TIOBE 排名的原文链接:https://www.tiobe.com/tiobe-index


C++ 与 Python 的协同效应

我们知道 Python 的一大应用场景就是科学计算(人工智能),为了程序可以运行的更快,人类可谓是用心良苦。

比如为特定算法设计硬件,但单单是有了硬件还不行 !Python 现阶段无法直接调用硬件,程序员还需要先用 C/C++ 开发好驱动程序,并暴露好相应的 API 给 Python 。

我遇到的多数情况都用不着设计专业的硬件,单单只是把算法用 C/C++ 重写一下,就能解决问题。

也就是说 Pythoner 一旦发现自己程序的性能不好,算法上也没有找到好的改进项,这个时候用 C++ 重写一下多数情况可以提升性能。 这正是 TIOBE 排行榜上近几年 C++ 与 Python 表现出正相关的原因。

TIOBE 排名的原文链接:https://www.tiobe.com/tiobe-index


C++ vs Python 性能测试

我之前遇到的 Python 性能问题大多数是它计算慢,当然也不排除其它人的模型主要是慢在 IO 上。一开始我也不觉得 Python 会在计算上慢多少,直到我自己在机器上分别用 C++ 和 Python 测试了一下,结果让我无语了,原来 C++ 这么强

我当时用的是计算“斐波那契数列”的第 n 位这个来测试的,一来测试的是计算,二来测试代码也简单;所以就选择了这个(这么少的测试样本自然是不能完全证明 C++ 比 Python 快多少的,但是可以做一个大概的把握)。

我们先看测试的结论(性能上看真的是一个天一下地)。

代码如下

代码语言:javascript
复制
#/usr/bin/env python3

"""
测试 Python & C++ 这两种语言计算 斐波那契数列 的快慢。
"""

from datetime import datetime

# 导入我们手写的 C++ 代码逻辑(后面会讲)
from plugins import cppmath

def fib(n):
    """求 斐波那契数列 的第 n 位的值
    Parameter:
    ----------
    n: int
        第 n 位

    Return:
    -------
    int
        返回斐波那契数列第 n 位的值
    """
    if n == 1 or n == 2:
        return 1
    else:
        return fib(n - 1) + fib(n - 2)

def main(n):
    """分别测试 C++ 和 Python 计算同一个数的耗时
    """
    start = datetime.now()
    res = cppmath.fib(n)
    end = datetime.now()
    print("C++ 计算的结果为    {} 总的耗时 {}(s)".format(res, end-start))

    start = datetime.now()
    res = fib(n)
    end = datetime.now()
    print("Python 计算的结果为 {} 总的耗时 {}(s)".format(res, end-start))

if __name__ == "__main__":
    main(40)

测试结果

代码语言:javascript
复制
python3 test-fib-speed.py 
C++ 计算的结果为    102334155 总的耗时 0:00:00.140350(s)
Python 计算的结果为 102334155 总的耗时 0:00:11.720886(s)

快了 80 几倍,我已经服了。

代码语言:javascript
复制
In [1]: 11.72/0.14
Out[1]: 83.71

C++ 部分的关键代码

其实算法的逻辑是一样的,只是换了一种语言,性能就能提升 80+ 倍,牛逼++

代码语言:javascript
复制
#include <Python.h>

// 用 C++ 实现 fib 函数
int fib(int n) {
    if (n == 1 || n == 2) {
        return 1;
    }
    else {
        return fib(n - 1) + fib(n - 2);
    }
}

// 把 C/C++ 的一个函数包装成一个 Python 函数
static PyObject *py_fib(PyObject *self,PyObject *args) 
{
    int x = 0,result = 0;
    PyArg_ParseTuple(args,"i",&x);
    result = fib(x);
    return Py_BuildValue("i",result);
}


// 定义模块要包含的函数列表
static PyMethodDef methods[] = {
    {"fib", py_fib, METH_VARARGS, "fib"},
    {0,0,0,0}
};

// 定义模块
static struct PyModuleDef module = {
    PyModuleDef_HEAD_INIT,
    "plugins",
    "extend cpython",
    -1,
    methods
};

// 定义模块的初始化方法
PyMODINIT_FUNC PyInit_cppmath(void)
{
    return PyModule_Create(&module);
}

一旦我们像上面一样完成了模块和函数的定义,Python 就能识别我们的 C++ 函数了,到时候就可以 import 进来直接调用。


C++ 学习推荐 大多数 C++ 书籍(大学教材)都是以 C++1998 年的标准编写,导致一方面还没有学完就已经过时了,另一方面用法也复杂,容易写出 Bug 。

近几年 C++ 标准越来越以人为本,它尽可能让编译器多做点事,让程序员更舒服一些。比如引入了智能指针,我再也不用怕手工分配的内存, 因为忘记释放导致内存泄漏了。引入了模块和协程 ... ... 等等一大堆好东西。这一切都在使 C++ 开发变得简单。如果现在学 C++ 的话,我首推《C++20实践入门》 + 《C++20高级编程》

如果硬要说这两套书有什么缺点的话,就是书的作者太激进了,全书都是用 C++20 标准写的,导致有部分特性编译器没有跟上,比如 “模块”,“format” ,到时候在 GCC 和 CLANG 上编译会有问题,但是在微软的编译器上是 OK 的(微软牛逼)。

还有一本基于 C++11 标准的也值得一读,它的优点就是讲的非常细,如果想成为这门语言的专家,那一定要读一读这一本。


最后

都到这里了,是时候图穷匕见了!我这人比较 real 就直说了,我想涨粉帮忙点下关注!我的技术文章质量还可以,关注应该不亏。

“在看” + “分享” + “点赞” + “收藏” 也是我继续写下去的动力;再次感谢!!!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-02-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 初代庄主 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档