静态编译python 源码-Python 最佳代码实践:性能、内存和可用性!

译者丨欲望

作者丨Satwik Kansal

日文原创丨

翻译丨

当今世界,遵循最佳实践的代码库受到高度重视。 如果您的项目是开源的,这可以成为吸引优秀开发人员的一种方式。 作为开发人员,您希望编写高效且优化的代码

使用尽可能少的视频内存,执行速度更快,看起来干净,文档齐全,遵循标准样式手册,并且对于新开发人员来说很容易理解。

这里讨论的实践可以帮助您为开源组织做出贡献、向 OnlineJudge 提交解决方案、使用机器学习解决大数据处理问题或开发您自己的项目。

做法一:尽量不要忽视显存

一个简单的Python程序在显存方面可能不会造成太多问题,但在高内存消耗的项目中,显存的使用就变得至关重要。 从一开始就开发一个大型项目时,明智地使用视频内存是明智之举。

与C/C++不同,Python类库会管理显存,用户很难控制。 Python 中的内存管理涉及一个专用堆,其中包含所有 Python 对象和数据结构。

该私有堆的管理由 Python 内存管理器在内部确保。 当您创建对象时,Python 虚拟机会处理所需的视频内存并决定将其放置在视频内存布局中的位置。

但是,更好地了解事物的工作原理和不同的处理方式可以帮助您最大限度地减少程序的内存使用量。

• 使用生成器来估计大量结果

生成器可以被延迟评估。 您可以通过遍历来使用它们:显式使用“for”或隐式地将其传递给任何方法或构造。

静态编译python 源码-Python 最佳代码实践:性能、内存和可用性!

生成器可以返回多个项目,就像返回一个列表一样——不是一次全部返回,而是一个接一个地返回。 生成器将暂停,直到请求下一个项目。 在此处阅读有关 Python 生成器的更多信息 [1]。

• 对于大量数字/数据的操作,您可以使用像Numpy 这样的库,它可以出色地处理内存管理。 • 使用format 而不是“+”来生成字符串- 在Python 中,str 是不可变的,因此每对连接必须将左右字符串复制到新字符串中。 如果连接四个宽度为 10 的字符串,则将复制 (10+10)+((10+10)+10)+(((10+10)+10)+10)=90 个字符,而不是 40 个字符。 随着字符串数量和大小的减少,情况似乎会变得更糟。 Java 有时会转换一系列连接以使用 StringBuilder 来优化这些情况,而 CPython 则不会。 为此,建议使用 .format 或 % 句子。 如果您无法在 .format 和 % 之间进行选择,请查看这个有趣的 StackOverflow 问题 [2]。 • 定义Python 类时使用槽。 您可以通过将类中的槽设置为固定的属性名称列表来告诉 Python 不要使用动态字典,并且只为一组固定的属性分配空间,从而消除了每个对象使用字典的开销。 在此处阅读有关插槽的更多信息 [3]。 • 您可以使用外部模块(例如resource 和objgraph)跟踪对象级别的内存使用情况。 • 在Python 中管理内存泄漏可能是一项繁重的任务,但幸运的是有一些工具(例如heapy)用于调试内存泄漏。 Heapy 可以与 objgraph 一起使用来观察 diff 对象的分配随时间的推移而下降。 Heapy 可以显示哪些对象占用了最多的视频内存。 Objgraph 可以帮助您找到回溯引用以了解为什么它们无法被释放。 您可以在此处阅读有关在 Python 中诊断视频内存泄漏的更多信息 [4]。

您可以在此处阅读 Theano 开发人员编写的有关 Python 内存管理的详细信息 [5]。

练习2:Python2或Python3

当开始一个新的Python项目,或者刚刚学习Python时,你可能会发现自己对于选择Python2或Python3感到非常沮丧。 这是一个广泛讨论的话题,网上有很多观点和很好的解释。

一方面,Python 3 有一些很棒的新功能。 另一方面,您可能想使用仅支持Python2的包,而Python3不向后兼容。 这意味着在 Python 3.x 库上运行 Python 2 代码可能会引发错误。

但是,可以编写在 Python2 和 Python3 库上运行的代码。 最常见的方法是使用 _future、builtins 和 6 等包来维护一个简单、干净的 Python3.x 兼容代码库,可以以最小的开销同时支持 Python2 和 Python3。

python-future 是 Python2 和 Python3 之间缺少的兼容层。 它提供了未来和过去的包来向前或向后移植Python2和Python3的功能。 它还附带futurize和pasteurize,各种基于2到3的脚本,可以帮助您轻松地将Py2或Py3代码模块逐个模块转换为干净的Py3风格的代码库,支持Python2和Python3。

请查看 Ed Schofield 的超酷 Python2-3 兼容代码手册 [6](翻墙)。 如果您更喜欢视频而不是阅读,您可以在 PyConAU2014 上找到他的演讲,“编写 2/3 兼容代码 [7]”(翻墙)。

实践3:编写漂亮的代码

共享代码是一种有益的尝试。 无论动机是什么,如果人们发现您的代码无法使用或难以理解,那么您的良好意图可能无法达到预期。 几乎每个组织都遵循开发人员必须遵守的样式手册,以确保一致性、易于调试和协作。 Zen of Python 就像一本迷你风格的 Python 设计手册。 主流的Python风格手册包括:

1. PEP-8 风格手册 2. Python 习惯用法和效率 3. GooglePython 风格手册

静态编译python 源码-Python 最佳代码实践:性能、内存和可用性!

指南讨论了如何使用:空格、逗号和花括号、对象命名手册等。尽管它们在个别情况下可能会发生冲突,但它们都有相同的目标——“干净、可读和可调试的代码标准”。

坚持使用手册,或遵守您自己的手册,但不要试图遵循与广泛接受的标准截然不同的东西。

使用静态代码分析工具

有许多开源工具可以使您的代码符合标准样式手册和编写代码的最佳实践。

Pylint是一个用于检测模块编码标准的Python工具。 Pylint 可以快速轻松地查看您的代码是否捕获了 PEP-8 的精髓,从而对其他潜在用户“友好”。

它还为您提供优秀的指标和统计报告,帮助您判断代码的质量。 您还可以通过创建自己的 .pylintrc 文件进行自定义和使用。

Pylint 不是唯一的选择 - 还有其他工具,如 PyChecker、PyFlakes 以及 pep8 和 flakes8 等软件包。

我的建议是使用 Coala,一个统一的静态代码分析框架,通过单一框架提供与语言无关的代码分析。 Coala 支持我之前提到的所有 linting 工具,并且是高度可定制的。

正确记录代码

这方面对于代码库的可用性和可读性至关重要。 仍然建议您尽可能广泛地记录代码,以便其他开发人员可以更轻松地理解您的代码。

函数的典型内联文档应包括:

• 函数的一行摘要。 • 提供交互式示例(如果适用)。 这些可以供新开发人员参考,以快速了解功能的使用和预期输出。 您还可以使用 doctest 模块来确保这些示例正确(作为测试方法运行)。 请参阅 doctest 文档中的示例。 • 参数文档(通常用一行描述参数及其在函数中的作用) • 返回类型文档(除非您的函数不返回任何内容!)

Sphinx 是一种广泛使用的工具静态编译python 源码,用于生成和管理项目文档。 它提供了大量便捷的功能,可以减少您编写标准文档的工作量。 据悉,您可以将文档推送到ReadtheDocs,这是托管项目文档最常用的形式。

Hitchiker 的 Python 文档指南 [8](由作者翻译成英文 - Python 最佳实践手册 [9])包含一些有趣的信息,这些信息在您编写代码文档时可能会很有用。

实践4:增强多进程性能,而非多线程

在提高多任务代码的执行时间时,您可能希望利用 CPU 中的多个内核同时执行多个任务。 形成多个线程并让它们同时执行似乎很直观静态编译python 源码,但是由于Python中的全局类库锁,所有线程轮流在同一个核心上运行。

对于 Python 中的实际并行化,您可能需要使用 Python 的多处理模块。 另一种解决方案可能是将任务外包给:

1. 操作系统(通过多处理) 2. 调用 Python 代码的一些外部应用程序(例如 Spark 或 Hadoop) 3. Python 代码调用的代码(例如,您可以让 Python 代码调用 C 函数,以执行昂贵的多线程的东西)。

不仅仅是并行性,还有其他方法可以提高性能。 其中一些包括:

• 使用最新版本的Python:这是最直接的方法,因为新的更新通常包括对现有功能的性能改进。 • 尽可能使用外部函数:这也符合 DRY 原则 - 内置函数是由世界上一些最好的 Python 开发人员精心设计和审查的,因此它们通常是最好的方法。 • 考虑使用Ctypes:Ctypes 提供了一个用于从Python 代码调用C 共享函数的套接字。 C是一种更接近机器级别的语言,代码执行速度比Python中的类似实现更快。 • 使用Cython:Cython 是Python 语言的超集,允许用户使用静态类型声明调用C 函数,从而生成更简单、执行速度更快的最终代码。 • 使用PyPy:PyPy 是另一种Python 实现,它具有JIT(即时)编译器,可以使代码执行得更快。 其实我从来没有尝试过PyPy,不过它也号称可以减少程序的内存消耗。 像 Quora 这样的公司实际上在生产中使用 PyPy。 • 设计和数据结构:适用于所有语言。 确保您为目标使用正确的数据结构,在正确的位置声明变量,明智地利用标识符范围,并在有意义的地方缓存结果等。

我可以举的一个具体例子是:Python在访问全局变量和解析函数地址方面通常很慢,因此将它们分配给当前范围内的局部变量然后再访问它们会更快。

实践 5:分析你的代码

一般来说,分析代码的覆盖范围、质量和性能很有帮助。 Python 附带了 cProfile 模块来帮助评估性能。 除了给出总运行时间外,它还单独对每个函数进行计时。

然后,它会告诉您每个函数调用的时间,这使得您可以轻松确定要优化的位置。 以下是 cProfile 的示例剖析:

• memory_profiler 是一个用于监控进程内存消耗情况的Python 模块,它可以逐行分析Python 程序的内存消耗情况。 • objgraph 可以显示占用Python 程序显存的前N 个对象、一段时间内删除或添加的对象以及脚本中对给定对象的所有引用。 • 资源为程序提供检测和控制系统资源使用的基本机制。 该模块的两个主要用途包括限制资源分配和获取有关资源当前使用情况的信息。

实践6:测试和持续集成测试

编写单元测试是一个好习惯。 如果您觉得编写测试不值得,请查看这个 StackOverflow 问题 [10]。 最好在编码之前或编码期间编写测试。 Python 提供了unittest 模块来为函数和类编写单元测试。 此外,还有以下框架:

•鼻子- 可以用更少的样板运行单元测试。 • pytest - 还运行单元测试,更少的样板,更好的报告和许多很酷的额外功能。

为了更好地进行比较,请阅读此处的介绍 [11]。

不要忘记 doctest 模块,它使用内联文档中的交互式示例来测试源代码。

检测覆盖范围

Coverage是一个检测Python程序代码覆盖率的工具。 它监视您的程序,关注代码的哪些部分已被执行,然后分析源代码以识别可能已执行但未执行的代码。

覆盖率测试一般用于检验测试的有效性。 它可以显示代码的哪些部分经过了测试,哪些部分没有经过测试。 一般建议是具有 100% 的分支覆盖率,这意味着您的测试应该能够执行并验证项目每个分支的输出。

持续集成

从一开始就为您的项目配置 CI 系统对您的项目非常有用。 您可以使用 CI 服务轻松测试代码库的各个方面。 CI 中的一些典型检测包括:

静态编译python 源码-Python 最佳代码实践:性能、内存和可用性!

• 在真实环境中运行测试。 在某些情况下,测试在某些架构上通过,而在另一些架构上失败。 CI服务允许您在不同的系统架构上运行测试。 • 对您的代码库实施覆盖率限制。 • 优化代码并将其部署到生产环境(您可以在不同的平台上执行此操作)

有一些 CI 服务:其中最流行的是 Travis、Circle(适用于 OSX 和 Linux)和 Appveyor(适用于 Windows)。 根据我最初的使用情况,像 SemaphoreCI 这样的新兴产品似乎很可靠。 Gitlab(另一个类似 Github 的 Git 存储库管理平台)也支持 CI,但就像其他服务一样,您需要显式配置它。

参考

[1]

[2]

[3]

[4]

[5]

[6]

[7]

[8]

[9]

[10]

[11]

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 源码编译 静态编译python 源码-Python 最佳代码实践:性能、内存和可用性! https://www.wkzy.net/game/168210.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务