专栏首页码海Gradle 编译速度提升 70%!怎么做到的?

Gradle 编译速度提升 70%!怎么做到的?

之前我司每个 Java 应用部署到预发都要等待漫长的编译打包时间,非常地痛苦!大项目编译时间常常达到接近 10 分钟,生命短暂啊,人生有多少个 10 分钟可以等待,于是我们的效能团队针对编译作了一些优化,提速非常明显,对某个应用的测试来看,编译时间从 160 s 缩短到了 50 s 左右,提升近 70%,大家纷纷点赞,那么效能团队做了哪些措施来让编译速度提升这么明显呢?

首先要说的是我们用的 Gradle 来作为我们的构建工具,所以主要是针对 Gradle 的命令来作了一些优化。

1、修改 gradle build 的参数

  • 使用 --build-cache

什么是 build cache(构建缓存),在 Gradle 中,每一个待编译的工程叫 Project,每一个 Project 在构建时都包含一系列的 task。

每个 task 的输入都可以作为下一个 task 的输出,build cache 做的事就是把可以缓存(注:并不是所有的 task 输出都能缓存)的 task 输出都缓存住,这样在构建过程中,如果发现这个 task 的输入不变,就没必要重新执行任务了,直接从 task ouput 缓存里拿即可,如下图示,Build 2 的构建输入直接从 Build Cache 中拿,这样 Build 1 就不用构建了。

效果怎么样呢,看下图,下面图分别显示了 Gradle 持续集成时使用构建缓存和不使用构建缓存两种情况下的聚合的构建时间,可以看到使用了 cache 的 Gradle 构建速度明显快于不使用 cache 的情况。

更骚的是这个 Buiid Cache 支持分布式的,可以统一把这些 cache 丢到一台机器上,本地机器要编译时统一去这台机器拉 cache,这样如果我们切换分支时执行构建也能用 Build Cache 来加快构建速度。

--build-cache 的具有使用需要注意一些事项,比如得 Gradle 4.3 以上才有效,建议大家直接去官网查查看。

  • 增加 --parallel 参数

并行执行在多项目编译的项目中能有效提升编译的速度,但是并行执行的前提是每个项目已经被模块化,每个项目之间没有耦合。

  • 移除 --refresh-dependencies 参数

原来 gradle build 有加这个参数,这个参数会忽略缓存,强制重新下载,显然是编译的瓶颈。

2、任务并行

原来 Jenkins 中执行 Gradle 编译任务,每个 Task 是串行执行的,总编译耗时是每个任务执行时间的总和。

现在把它改成了并行的

显然并行执行会快得多。

3、将大项目工程中的常用代码抽成 jar 包

对于业务方来说,采用这种方式也是提升编译速度的有效手段 ,将大量代码抽成 jar 包,意味着它们本身就是字节码了,在 gradle build 时就不用编译啦。自然能提升整个工程的编译打包时间。

本文分享自微信公众号 - 码海(seaofcode),作者:码海

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 巧用递归解决矩阵最大序列和问题

    之前同事问了一道需要点脑洞的算法题,我觉得蛮有意思的,思路可能会给大家带来一些启发,在此记录一下

    kunge
  • 一文学会回溯算法解题技巧

    上文我们学习了深度优先搜索和广度优先搜索,相信大家对这两者的算法有了比较清楚的认识,值得一提的,深度优先算法用到了回溯的算法思想,这个算法虽然相对比较简单,但很...

    kunge
  • 一文学会排列组合

    上一篇「一文学会递归解题」一文颇受大家好评,各大号纷纷转载,让笔者颇感欣慰,不过笔者注意到后台有读者有如下反馈

    kunge
  • 深度优先搜索遍历与广度优先搜索遍历

    1、图的遍历      和树的遍历类似,图的遍历也是从某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问。它是许多图的算法的基础。      ...

    阳光岛主
  • 运维管理之线上故障处理原则

    墨菲定律暗示我们,如果担心某种情况会发生,那么它更有可能发生,久而久之就一定会发生。这警示我们,在互联网公司,对生成环境发生的任何怪异现象和问题都不要轻视,对其...

    lyb-geek
  • ThreadInfo结构和内核栈的两种关系

    本来本节是要学习内核启动的第一个进程的建立,也就是0号进程,也称idle进程,也称swapper进程。但是在学习第一个进程建立之前需要先学习threadinfo...

    DragonKingZhu
  • 一个python程序

    a = [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]

    py3study
  • servlet 核心技术

    在 servlet 生命周期中,servlet 容器完成加载 servlet 类和实例化一个 servlet 实例,并通过3个方法来完成生命周期中的其他阶段。

    希希里之海
  • Typecho友情链接插件禁用之后重新启动报500错误的解决方法

    laulzgoay
  • Grunt快速入门

    Grunt是基于JavaScript的命令行构建工具,它可以帮助开发者们自动化重复性的工作。你可以把它看成是JavaScript下的Make或者Ant。它可以完...

    用户2936342

扫码关注云+社区

领取腾讯云代金券