写点什么

从此告别代码泄露!提高 Python 性能的必备技巧

作者:LLLibra146
  • 2024-11-16
    北京
  • 本文字数:1708 字

    阅读完需:约 6 分钟

引言

前面的文章提到了使用 Pyarmor 来保护自己的 Python 代码,Pyarmor 通过加密源代码来保护我们的代码。但是 Pyarmor 是收费的,即使是有免费许可证,但是大批量使用的话还是一笔不小的成本,在不需要许可证机制保护代码的情况下可以考虑使用 Cython 来保护我们的 Python 代码。


Cython

Cython 是一种编程语言,它是 Python 的超集,允许开发者在 Python 代码中嵌入 C 语言的特性。Cython 主要用于提高 Python 代码的执行速度,同时也可以将 Python 代码编译为 C 扩展模块,从而增加代码的保护性。

Cython 安装

Cython 的安装很简单,直接使用 pip 安装就可以,我这里使用 poetry 来安装依赖。由于 Cython 会将 Python 代码编译为本地机器码,所以在使用 Cython 进行编译时,需要使用到当前平台的编译器。由于我使用 Mac,系统已经自带了,所以这里不需要重复安装了,如果使用 Windows 系统的话需要安装 C++编译器。


poetry add cython# orpip install cython
复制代码

示例脚本

这里先准备一个示例脚本,脚本会做一个累加计算,并且访问百度获取响应。


# cython_test.pyimport timefrom contextlib import contextmanager
import requests

def sum_of_squares_cython(int_list): n = len(int_list) result = 0 for i in range(n): result += int_list[i] ** 2 return result

def get_response(): return requests.get('https://www.baidu.com').text[:100]

@contextmanagerdef timer(): t = time.time() yield print(f'运行时间为:{time.time() - t:.4f}')
复制代码


# demo.pyfrom cython_test import get_response, sum_of_squares_cython, timer
if __name__ == '__main__': with timer(): print(sum_of_squares_cython([a for a in range(1000000)])) print(get_response())
复制代码


运行以上代码,得到以下结果:


333332833333500000运行时间为:0.2355<!DOCTYPE html><!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charse
复制代码

编译

创建 setup.py ,执行编译指令。


# setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup( name='test_cython_project', ext_modules=cythonize("cython_demo/cython_test.py", language_level=3),)
复制代码


使用以下代码编译代码:


python cython_demo/setup.py build_ext --inplace
复制代码


编译完成后,可以看到文件夹内生成了对应的 c 文件和 Mac 平台的 so 文件。c 文件有一万多行,这个时候调用 so 文件就可以不再需要解释器了,运行的就是本地的机器码,会快很多。



测试运行结果

将之前的 cython_test.py 删除或者改名,让 Python 无法找到它,不然 Python 会重新导入它。然后 Python 就会导入对应的 so 文件, so 文件其实和 Python 模块是一样的,可以直接当做模块调用,代码都不用改。


改完名后,重新运行之前的代码:


333332833333500000运行时间为:0.2133<!DOCTYPE html><!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charse
复制代码


从累加的时间上来看,大概比之前运行快了 0.02 秒吧,而且多次运行也很稳定,达到了加速代码运行的目的。

编译产物

而且编译产物是 so 文件,这个文件是二进制的,现在好多 Python 的依赖模块都是通过 Cython 编译的,并且在分发依赖的时候分发的就是 so 或者 pyd 文件,这样主要是为了加快 Python 原生代码的运行速度。


查看 so 文件:



可以发现,编译后的 so 文件的确是苹果系统的可执行文件,和 Windows 上的 pyd 文件是一样的。

Cython 模块分发

Cython 模块编译后,编译产物是二进制文件,如果要分发的话可以直接分发编译产物。这个时候用户是无法看到模块对应的源代码的,但是要注意分发的时候要将模块的依赖一起分发,防止在运行时找不到依赖。

总结

Cython 是一种强大的工具,不仅可以提高 Python 代码的性能,还能保护我们代码的知识产权。Cython 编译后的产物可以明显增加逆向工程的难度,保护我们的代码不被盗用。如果我们的需求仅仅只是保护代码,不需要许可证机制并且不需要特别强大的加密的话,可以优先使用 Cython,兼容性和性能会比 Pyarmor 更好一些。 

发布于: 刚刚阅读数: 3
用户头像

LLLibra146

关注

还未添加个人签名 2018-09-17 加入

还未添加个人简介

评论

发布
暂无评论
从此告别代码泄露!提高Python性能的必备技巧_Python_LLLibra146_InfoQ写作社区