Python计算加速利器

迷途小书童的 Note

读完需要

6
分钟

速读仅需 2 分钟

1

简介

Python 是一门应用非常广泛的高级语言,但是,长久以来,Python的运行速度一直被人诟病,相比 c/c++、java、c#、javascript 等一众高级编程语言,完全没有优势。

那么真的没有办法提升 Python 程序的运行速度吗?相信看完本文,你应该会有答案。

2

示例

这里以找出 1000000 以内的质数为例,分别计算下需要花费多长的时间?

首先来回顾下什么是质数?

质数(Prime number),又称素数,指在大于 1 的自然数中,除了 1 和该数本身外,无法被其他自然数整除(也可定义为只有 1 与该数本身两个因数)。举个例子,比如说数字 7,从 2 开始一直到 6,都不能被它整除,只有 1 和它本身 7 才能被 7 整除,所以 7 就是一个质数。

下面来看看 python 的代码实现

javascript 复制代码
import math
import time




def is_prime(num):
    if num == 2:
        return True
        
    if num <= 1 or not num % 2:
        return False


    # 从3开始,到int(根号num)+1,步长是2,如3,5,7 ...
    for i in range(3, int(math.sqrt(num)) + 1, 2):
        if not num % i:
            return False


    return True




def run_program(N):
    for i in range(N):
        is_prime(i)




if __name__ == '__main__':
    N = 1000000
    start = time.time()
    run_program(N)
    end = time.time()
    print(end - start)

执行代码,可以看到在我的老旧 i5 机器上总共花费了 5 秒多

3

改进

大家都知道解释型语言,解释器不产生目标机器代码,而是产生中间代码,解释器通常会导致执行效率较低。

因此,问题就变成了,能不能将 python 代码翻译成机器码?那执行效率肯定就会大大提升了

numba 就是这么一款工具,它是 python 的即时编译器(just-in-time compiler),它使用 LLVM 将 python 代码翻译成机器码,特别是在使用 numpy 数组以及循环操作上,效果最佳。

numba 的使用比较简单,我们不需要更换 python 的解释器,只需要将 numba 的装饰器写在 python 方法上,当这个带有 numba 装饰器的方法被调用时,就会被 just-in-time 即时编译为机器代码,然后执行。目前 numba 支持在 X86、ARM 等多种架构上进行动态编译。

使用 numba 之前,我们需要安装这个库

javascript 复制代码
pip install numba


或者
conda install numba

下面来看看 numba 版本的质数问题

javascript 复制代码
import math
import time
from numba import njit




@njit(fastmath=True, cache=True)
def is_prime(num):
    if num == 2:
        return True
    if num <= 1 or not num % 2:
        return False


    for i in range(3, int(math.sqrt(num)) + 1, 2):
        if not num % i:
            return False
    return True




@njit(fastmath=True, cache=True)
def run_program(N):
    for i in range(N):
        is_prime(i)




if __name__ == '__main__':
    N = 10000000
    start = time.time()
    run_program(N)
    end = time.time()
    print(end - start)

执行上述代码,可以看到,速度提升了 4 倍左右,不到 1 秒,效果还是非常明显

最后,作为横向比较,我们使用 c++ 语言,也写一个类似的程序

javascript 复制代码
#include <iostream>
#include <cmath>
#include <time.h>


using namespace std;


bool isPrime(int num)
{
    if (num == 2) 
        return true;
    if (num <= 1 || num % 2 == 0) 
        return false;
    double sqrt_num = sqrt(double(num));
    for (int i = 3; i <= sqrt_num; i += 2) {
        if (num % i == 0) 
            return false;
    }
    return true;
}


int main()
{
    int N = 1000000;
    clock_t start, end;
    start = clock();
    for (int i=0; i < N; i++) 
        isPrime(i);
    end = clock();
    cout << (end - start) / ((double)CLOCKS_PER_SEC);
    return 0;
}

编译后执行,可以看到,只花了 0.4 秒

4

小结

从上面的对比示例中可以看到,使用了 just-in-time compiler 后(numba、pypy 都是类似的实现),代码的执行效率已经直逼 C++ 等编译型语言了。

5

参考资料

6

免费社群

相关推荐
Ares-Wang15 分钟前
Flask》》 Flask-Bcrypt 哈希加密
后端·python·flask
kongba00744 分钟前
项目打包 Python Flask 项目发布与打包专家 提示词V1.0
开发语言·python·flask
froginwe111 小时前
C 语言测验
开发语言
belldeep1 小时前
介绍 遗传算法 与 TSP问题
python·遗传算法·ga·tsp问题
解救女汉子1 小时前
SQL触发器如何获取触发源应用名_利用APP_NAME函数追踪
jvm·数据库·python
今夕资源网1 小时前
powershell工具包 安装升级脚本并设置UTF-8 环境快捷方式创建 将powershell的编码默认改为UTF-8
开发语言·utf-8·powershell·utf-8编码·powershell7·powershell5·设置utf-8编码
机器视觉知识推荐、就业指导2 小时前
Qt:真正的门槛不是入门,而是维护
开发语言·qt
hhb_6182 小时前
Dylan 语言核心特性与工程实践深度解析
开发语言·c#
思绪无限2 小时前
YOLOv5至YOLOv12升级:血细胞检测系统的设计与实现(完整代码+界面+数据集项目)
人工智能·python·深度学习·目标检测·计算机视觉·yolov12·血细胞检测
无巧不成书02182 小时前
零基础Java网络编程全解:从核心概念到Socket实战,一文打通Java网络通信
java·开发语言·网络