使用Cython提高python代码执行速度

2022.2.21更新

  • python程序执行效率是明显低于c的。
  • 优化python代码的一个思路就是:将python的核心代码(一般是需要多次调用,或核心循环部分)转换成c语言。
  • 不需要将程序重新改写成c,只需要用Cython包将python程序进行转换即可。

1.Cython包

  • Cython包的安装参见https://pypi.org/project/Cython/
    pip install Cython
    conda install Cython
  • 一般安装anaconda的时候就带有Cython包;可以查看一下是否已经有这个包了。(直接在程序里 import Cython,若不报错就说明有;也可以通过pip list等查看)

2.python–>c

2.1

  • 将需要转换的程序重命名为xxxx.pyx;
    例如我有一个封装好的类.py文件word_frequency.py,需要重命名为word_frequency.pyx

2.2

  • 在相同的目录中创建一个文件setup.py;作用:使用cython编译器去编译pyx文件
from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules=cythonize("word_frequency.pyx"))

2.3

  • 开始编译,在命令行中:
    python setup.py build_ext --inplace
    (# inplace表示源代码在同一目录下)

  • 若编译成功,则在目录下会出现两个文件:word_frequency.cword_frequency.cp38-win_amd64.pyd(若在Linux平台下会出现word_frequency.cp38-win_amd64.so),此时.so文件或者.pyd文件就可以像普通的python文件一样,被import

  • 上述文件中word_frequency.c没有什么用,可以删除掉;word_frequency.cp38-win_amd64.pyd文件可以重命名为word_frequency.pyd不重新命名也可以,载入from word_frequency import word_frequency不受影响。

2.4

  • 在其他文件中正常调用word_frequency.pyd即可(可以将word_frequency.py改为其他名字,以免调用错)。
from word_frequency import word_frequency #一样的import

wordFreq = word_frequency(dict_fullpath) #一样的使用方法

2.5

  • 对比
转换前:130.40097641944885 s
转换后:68.84645509719849 s
  • 速度只提升了一倍左右。
  • Cython能比常规Python代码快多少实际上取决于代码本身。例如,如果运行成本较高的多变量循环,Cython明显优于常规的Python代码。递归函数同样使得Cython快于Python。

3 关于.pyd文件

  • 若想对python文件进行加密,会把python模块编译成.pyd文件
  • pyd文件是由 D语言编写的一种dll 文件,目前还没有办法进行反编译,只能被反汇编。给python文件提供了很高的安全性。而且也可以编写一些python插件,方便python开发。



2022.2.22更新

4、python版本对.pyd文件加载的影响

出错点1:

  • 1)在python3.8.8版本将word_frequency.pyx编译成word_frequency.cp38-win_amd64.pyd
  • 2)在python3.8.8版本中,word_frequency.cp38-win_amd64.pyd能够被其他文件正常载入;from word_frequency import word_frequency没有问题。
  • 3)当把word_frequency.cp38-win_amd64.pyd移植到python3.7.4版本的电脑上时,from word_frequency import word_frequency会出现如下错误:
    在这里插入图片描述

“我以为是高版本的python 编译的内容无法被低版本的python加载”
“所以,我把编译和加载的版本换了一下(移植顺序换了一下)”


出错点2:

  • 1)在python3.7.4版本将word_frequency.pyx编译成word_frequency.cp37-win_amd64.pyd
  • 2)在python3.7.4版本中,word_frequency.cp37-win_amd64.pyd能够被其他文件正常载入;from word_frequency import word_frequency没有问题。
  • 3)当把word_frequency.cp37-win_amd64.pyd移植到python3.8.8版本的电脑上时,from word_frequency import word_frequency同样会出现如下错误:
    在这里插入图片描述

“所以,可能并不是高低版本兼容的问题”
“只能在对应的python版本上编译,然后加载运行;这意味着必须在本地编译,这就给用户操作上带来了一些麻烦;需要简化”
“将编译的代码也放在getWordFreq_Month.py中,虽然是本地编译,但是不需要用户操作命令行,即用户和原来的使用方法一样”


改善:

  • getWordFreq_Month.py中添加如下代码,(也要保证setup.pyword_frequency.pyx在相同目录下)
#将word_frequency.py编译成c
flag = True
file_list = os.listdir('./')
for file_name in file_list:
	#文件后缀是否有'.pyd'的
    file_suffix = os.path.splitext(file_name)[1]
    if file_suffix == '.pyd':
        flag = False
        
#判断是否需要在本地重新编译       
if flag:
    try:
        os.system('python setup.py build_ext --inplace')
    except:
        try:
            os.system('python3 setup.py build_ext --inplace')
        except:
            print('编译c存在问题!')
            sys.exit(0)
            
#加载   
from word_frequency import word_frequency



2022.2.23更新

5.如何彻底解决.pyd文件在其他python版本上无法加载的问题

出错点:

  • 1)虽然第4步的操作,把编译成c的过程放在了每台主机本地了,但是在一台python3.9版本的主机上,依然报错了:
    在这里插入图片描述
  • 2)在一台python3.6版本的主机上也出现了错误:
    在这里插入图片描述
  • 3)两个错误均是Unable to find vcvarsall.bat,查了一下vcvarsall.bat这个文件好像还和visual stdio相关,比较麻烦。
  • 4)出错的地方还是在编译的地方,就是python setup.py build_ext --inplace这句命令会出错。

“所以,虽然吧编译的程序放在了每台主机上,但是仍然会存在各种问题,移植性还是不好。”
“既然移植性不好搞定,那就直接封死吧,不再依赖python”


改善:
用pyinstaller将getWordFreq_Month.py文件封装成getWordFreq_Month.exe,可以脱离python环境。

  1. 安装pyinstaller
pip install pyinstaller
  1. 在.py目录中执行如下命令行:
pyinstaller -F getWordFreq_Month.py   #-F 选项,该选项指定生成单独的 EXE 文件,因此,在 dist 目录下生成了一个单独的大约为 6MB 的 xxxx.exe 文件
或者
pyinstaller -D getWordFreq_Month.py  #当生成完成后,将会在 xxxx目录下看到多了一个 dist 目录,并在该目录下看到有一个 xxxx 子目录,在该子目录下包含了大量 .dll 文件和 .pyz 文件,它们都是 xxxx.exe 程序的支撑文件。

在这里插入图片描述
via:手把手教你把Python代码转成exe
Python PyInstaller安装和使用教程(详解版)

  1. 执行xxxx.exe时,结果会一闪而过,所以需要通过命令来显示.exe文件的输出。在写一个start.bat文件,内容:
@echo off
dist\getWordFreq_Month\getWordFreq_Month.exe
pause

完工!

参考:

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值