Python Package Manager Shootout的使用教程

118 阅读6分钟

我为Python包管理器建立了一个基准,你可以在lincolnloop.github.io/python-pack…

当开始一个新的Python项目时,对于如何管理你的依赖关系,你有几个不同的选择。像Node.js有 npm, yarn, pnpm,以及 bun一样,Python 有 pdm, pip-tools, pipenv、 、 和 poetry(和其他)。

它们在很大程度上做着同样的事情,而且每个人的粉丝通常会吹嘘他们的选择为什么更好。根据功能来比较工具是很容易的,但是没有任何好的方法来了解它们在性能上的比较。缓慢的工具是开发者经常感到沮丧的一个来源。在项目的生命周期中,你要花多少时间来等待软件包在本地或在CI中安装?

考虑到这一点,我开始为这些项目建立一个公正的基准。

一个现实世界的例子

要解决的第一个问题是找到一个足够复杂的现实世界中的软件包来工作。直到你的依赖列表足够大,而且解决依赖链的问题非同小可时,缓慢工具的痛苦才会真正出现。我从Sentry的人那里找到了一个很好的例子。他们的产品在很大程度上是开源的,而且足够复杂,他们的 requirements.txt构成了一个很好的语料库来运行基准测试。它也很有趣,因为它至少包括一个需要编译的依赖项,而不是下载一堆二进制/纯Python包。

基准的操作

所有这些工具的工作方式略有不同,但总体概念或多或少是相同的。我决定对以下操作进行测量。

  • 工具的安装。安装工具本身需要多长时间?
  • 导入需求。向项目中添加所有的depencencies需要多长时间?
  • 锁定:生成一个锁定文件(解决依赖链,钉住所有的依赖,并获取软件包的发布哈希值)需要多长时间?
  • 安装。安装所有的依赖项需要多长时间(包括冷缓存和热缓存)?
  • 更新:更新所有的依赖项需要多长时间?
  • 添加软件包:添加一个新的软件包到依赖列表中需要多长时间(包括安装和重新锁定)?

谎言,该死的谎言,和基准测试

每当你发布一个基准,人们就会从树林里出来,告诉你所有不正确的方法。我知道我需要建立一个可重复和可审计的东西。我希望软件包管理人能够为这个 repo 做出贡献,以确保他们的项目得到公平的体现(他们已经做到了!)。我还希望人们能够轻松地将新的工具添加到基准中。考虑到这一点,我的结果是这样的...

GitHub行动

发布用于执行基准的代码是必然的,但我想更进一步。我很懒,不想在每次有人做出改变或发布新版本的软件包管理器时都要重新运行该基准。我也不想手动更新网站上的结果。所以我把整个事情自动化了。

GitHub Actions为我提供了自动化所需的一切。它可以按计划重新运行基准,然后解析结果并更新网站(发布在GitHub Pages上)。由于这些都是在共享硬件上运行,并依赖于外部网络资源,所以结果存在差异性。为了解决这个问题,我们公布了一些运行的平均结果。

构建基准测试

我希望GitHub的工作流程文件是由机器生成的,以便于添加新的工具,而不需要一个容易出错的复制/粘贴/替换过程。我需要某种方式将每个工具的独特命令抽象为一套共享的命令,以便于模板化。每个人都爱恨交加的工具--"制造",完美地满足了这个要求。我们的 制作文件提供了一个覆盖所有差异的轻量级抽象层。有了这个,我就可以使用一个通用模板,用一个简单的bash脚本组装工作流文件,其中包括 envsubst.

时间安排

time 命令(而不是内置的shell函数)拥有测量各个命令性能所需的一切。将它们包裹在make中可能会产生最微小的开销,但我怀疑它是如此之小,以至于被四舍五入了。time ,让你以任何你想要的格式输出到一个文件。我让它以CSV格式输出,并将每个软件包管理器的所有操作收集到一个文件中。

聚合

每个工具基准都作为一个单独的作业在GitHub Action上并行运行。当每个作业完成后,它将其结果CSV作为一个工件上传。当所有的工作完成后,我们运行一个最后的工作,将CSV收集并合并成一个文件(感谢sqlite-utils !),并将其作为一个新的工件存储。

我利用了较新的工作总结功能,以及 mdtable在GitHub Actions的网页界面上显示CSV的漂亮表示,这对于调试来说是非常宝贵的。

建立网站

一旦基准完成,一个新的工作流程就会启动,用新的数据重建网站。这包括。

  1. 下载汇总的数据
  2. 将Python中的数据转换为Chart.js所期望的格式
  3. 用以下方法构建静态网站 parcel
  4. 生成一个开放的图象,用 shot-scraper这样,当链接被分享时,我们就能得到一个漂亮(而且准确)的图形预览。
  5. 将文件推送到gh-pages ,并让它通过GitHub页面部署。

收尾工作

到目前为止,这一切似乎都能很好地衔接起来。它是不是设计得过头了?可能有点吧!不过,我对这个结果很满意。它是完全可审计的,我不需要回答关于我的笔记本和网络连接以及测试时月亮的位置的问题。它不需要维护任何基础设施,并且使用了很多基本的Linux结构,这些结构在几年后仍然可以工作。外部依赖性很小,所以我预计它不需要太多的维护。

解释结果

所有这些软件包管理器都是Python社区中的人们自愿付出的数千小时的成果。请不要用这些结果来羞辱或贬低这些项目或它们的维护者......那里已经有太多的毒害了。我公布这些结果的目的是为了让那些正在评估软件包管理器的人能够获得无偏见的性能信息。我也希望维护者能发现它对识别这些工具有改进空间的地方很有帮助(它已经发现了一个重大的退步!)。一个更快的Python生态系统对每个人来说都是更好的。

如果你有关于如何改进这个基准的建议,请不要犹豫,创建一个问题或提交一个拉动请求。