背景:
我们都知道python是解释型语言,而java、c++等都是编译型语言。那么解释型语言的速度是赶不上编译型的。
编译型语言一次编译的速度可能有点慢,但是后续如果要再次执行就会很快了(原因在于第一次编译后生成的二进制机器代码速度会很快)
而对于python这样的解释型语言,就没有这么好运气了,因为它每次执行都得一条条用解释器解释:第一次执行先把源码翻译成为.pyc中间字节码,然后后续如果没有发生代码更改才会一直用.pyc解释成为机器码,可即便如此,.pyc解释成为机器码每次都得用解释器一条条解释,所以速度赶不上一次编译成为机器码的java等语言。
java测试程序段处理速度:
public class test1 {
public static void main(String[] args){
int i;
int j;
int k = 1;
long startTime = System.nanoTime();
for (i = 0;i < 1000; i++) {
for (j = 0;j<1000;j++) k += j;
}
System.out.println(k);
long endTime = System.nanoTime();
System.out.println((endTime - startTime)/1000000.0);
}
}
499500001
2.5251 //2.5ms
python测试程序段处理速度:
def fib_py():
i = 1
j = 1
k = 1
for i in range(1000):
for j in range(1000):
k += j
return k
import time
# 获取当前时间戳,单位为纳秒
start_time_ns = time.time_ns()
res_py = fib_py()
print(res_py)
# 再次获取时间戳
end_time_ns = time.time_ns()
# 计算差值,单位为毫秒
duration_ms = (end_time_ns - start_time_ns) // 1000000
print(duration_ms)
499500001
28 # 28ms
cython的使用:
在计算密集型代码块中,如果对速度、执行效率要求比较高,我们可以使用c与python结合来提显著提升python效率。
Cython 是一个静态类型的 Python 超集,它允许你使用类似于 C 或 C++ 的类型声明来编写 Python 代码。Cython 的主要目的是为了提高 Python 代码的执行效率。当你的 Python 代码被 Cython 编译器处理时,它会被转换为 C 或 C++ 代码,然后通过标准的 C/C++ 编译器(如 GCC)编译成机器码。
这个过程实际上就是将一部分或全部的 Python 代码转换为编译型语言,再编译成二进制形式。
编译环境准备:
在pyCharm结合python解释器解释python后,您还需准备机子上配置C/C++编译器,本来试想这能否使用Dev-C++软件三自带的MinGW,配置MinGW\bin为系统变量Path作为环境变量,用来支持cython编译,可是发现不支持,需要安装visual studio c++编译工具,这里是个坑,希望大家不要跳。
准备cython库:
pip install cython
安装visual stuido c++编译器:
https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/
(下载安装buildTools在visual studio installer选中要安装的IDE集成开发工具,里面包含基本的c/c++编译器,建议把其他不必要的取消勾选,因为默认勾选的有好几个G)
给c/c++编译器配置环境变量,以便python环境中编译cython时能找得到编译器:
安装位置可以看得到,我的是:
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.40.33807\bin\Hostx64\x64
编辑环境变量 —> 系统变量 —> Path 新增该路径
编写cython测试程序:
loop.pyx
def func():
cdef int a = 1
cdef int b = 1
cdef int c = 1
for a in range(1000):
for b in range(1000):
c = c + b
return c
cython代码构建、打包成为c/c++编译程序的setup.py:
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("loop.pyx")
)
进行编译处理:
python setup.py build_ext --inplace
生成了下面二进制文件:
调用cython编译好后的扩展程序:
use_loop.py
import loop
import time
# 获取当前时间戳,单位为纳秒
start_time_ns = time.time_ns()
res = loop.func()
print(res)
# 再次获取时间戳
end_time_ns = time.time_ns()
# 计算差值,单位为毫秒
duration_ms = (end_time_ns - start_time_ns) // 1000000
print(duration_ms)
测试速度:
499500001
1 # 1ms
速度还是特别快的,所以这可以作为解决python速度问题的一种手段,至于用在哪些地方、巧妙的使用它,这是一个有待深入学习的话题@_@。