布莱恩•约翰
好吧好吧,我道歉clickbait标题。但这一次真的是一个奇怪的技巧和它真正的(也许)将提高你的包的性能。不,我不是指的工作参数,虽然我们在这个问题上让我们谈谈。
注意我要运行基准测试使用以下依赖版本与一个8核i9的Macbook Pro 32 g的内存:
- Rails 6.1.3.1
- Ruby 3.0.1
- 打包机2.2.15
——工作
这是一个常用的参数与包安装来提高性能。根据文档:
——工作=(<数字>),- j(<数字>)的最大数量并行下载和安装工作。缺省值是1。
现在看起来很整洁。让我们尝试新的Rails项目。
第一个设置:
rails美元新bundle-install-performance <剪> $宝石卸载————力——沉默#清除宝石我们可以安装基准
现在让我们看看性能就像默认情况下:
时间安装包安装<剪>包90.16美元29.66用户年代系统cpu 1:26.08 139%
好,现在我们有大约一分半钟的基线。让我们尝试,工作参数来加快速度。因为我使用一个8核的机器,让我们尝试1每核心工作:
美元的时间包安装,工作8 <剪>包安装,工作8 86.79用户28.04年代系统138%的cpu 1:22.91总数
嗯…这似乎并没有帮助很难。我想我们可能拿起几秒钟。为了排除上下文切换,让我们试一试——工作4:
时间美元包安装,工作v <剪>包安装,工作4 87.18用户25.16年代系统cpu 1:23.41 134%
好吧,看起来差不多。
但是为什么呢?我们有8核和大量的内存,为什么没有更多的就业机会让这更快?嗯,据我所知好像打包机使用线程的并行性,这意味着我们的老朋友吉尔/ GVL至少在玩,当使用核磁共振。
在一个较高的水平,这意味着我们可以并发I / O操作,而不是CPU操作(这不是100%正确,但我们可以花一整个系列的博客文章)。Rails包括一群本地珠宝扩展默认情况下,这意味着他们必须被编译,这意味着大量的CPU操作。
它看起来像打包机从核磁共振在2014年使用进程线程,原因似乎真正稳固。所以我不认为这是很快就会改变。
使环境变量
所以我们知道更多的线程似乎不帮助我们,至少不是与我们默认Rails / MRI设置,那我们可能会需要一个方法涉及多个CPU核为了使用并行性,以加快速度。打包机似乎并没有任何的框,将帮助我们,会什么?
好了,事情就是这样,大多数原生扩展使用rake-compiler库,它使用使在引擎盖下,也发生在支持——工作参数:
- j(工作),——工作(=工作]
指定的数量工作(命令)同时运行。如果有不止一个- j选项,最后一个是有效的。如果- j选项没有给出一个论点,使不限制工作的数量可以同时运行。
——工作参数的优点是,它实际上在CPU核上并行化。如果我们能找到一种方法通过参数运行时包安装,我们应该能够加快速度。
原来,有一种方法可以做到这一点,事实上我们可以看到它被用于rake-compiler-dev-box图书馆为了提高编译性能:
回声的出口使美元=“- j $ (nproc) "> > $ home / . bash_profile
整洁!看起来我们可以使用环境变量通过一个自定义的命令,包括——就业(或- j)参数!让我们试一试:
时间使美元= "——工作8”包安装<剪>包安装36.004 133.25 35.47用户年代系统468%的cpu
哇!36秒? !加速我们的包安装增长了近3倍,一个很好的进步。
包装起来
如果你的Gemfile一群本地扩展,和你使用核磁共振成像,然后您可以使用环境变量通过——就业观点,它可能会大幅提高包安装性能(假设你有多个可用的CPU核,购者自慎,等等)。
关于作者
布莱恩2017年加入BetterUp作为一个完整的堆栈高级工程师。他住在明尼阿波利斯地区与他的妻子和两个儿子。布莱恩是一个热爱家庭时间,徒步旅行、骑自行车、视频游戏、和串行优化。


加入谈话