近期我们都在讨论build系统,我们看了一些技巧能够让你的Maven build更快。

结论和反映都势不可挡。由于我们提供的技巧,很多其它的人都非常高兴能加快他们完毕自己的项目。如今,让我们看一下怎么处理gradle编译项目。

编译的项目一般都是标准编译的,也都是独一无二的。差点儿全部的项目都添加了其自身的复杂性。

全部的东西都不同可是有一个东西是相同的:编译会占用你的时间,加快编译会影响你的开发效率,让你的项目工作更加顺畅。

事不宜迟,让我们来看看什么是Gradle。和它的理念:

加速Gradle编译

这篇文章主要是由Madis Pink大力提倡的:Squeezing the Last Drop of Performance Out of Your Gradle Builds.Madis是JRebel的Androidproject师,所以假设你是一个搞Android的,我建议你应该试一下。Madis热衷于这些,可是你不会观察到有关他太多。

对于一个測试项目我们用Madis用过的代码:一个Android项目demo iosched(http://github.com/google/iosched)。不要害怕。gradle对于Android项目和你的Java项目是一样的。

这意味着我给你的建议相同适用于你其它的项目的环境。

所以你相同也能用这些技巧去加速你的JAVA项目编译。

在開始优化之前,我们首先须要理解一下Gradle的生命周期。它被拆分为3个不同阶段:

  1. 初始化:扫描项目,找出哪些内容须要被编译
  2. 配置:运行build.gradle脚本,创建任务图
  3. 运行:构建你APP实用的部分

如今你是不是头痛了?确实有一个实用的阶段。我们或许能够在我们自己的编译脚本加快,Gradle全然运行自私的任务:配置本身和实施运行开销。

在这篇文章中。我们将首先集中精力降低构建的开销之前,我们尽量使构建本身更快。

让我们開始一步优化构建步骤,同一时候測量进度。假设你想自己运行 iosched,从GitHub得到它,就像这样:

git clone http://github.com/google/iosched
cd ioshed

如今我们准备去克隆了!

让我们用手中典型的开发环境用gradle去build这个APP来获取依赖。

再次编译我们的项目,可是用dry-run(能够让gradle去跳过全部任务的运行)。

这意味着,我们将运行配置gradle,并运行全部它一般会做的任务仅仅是没有做实际工作。这正是我们须要測试而且降低开销的。

运行以下命令几次。由于你第一次做这种构建将拉低所需的依赖,假设你使用一个新的项目。运行以下的命令:

./gradlew :android:assembleDebug --dry-run

在考虑到全部的gradle运行的任务之后,跳过dry-run,会打印出运行这个命令会消耗多少时间。在我的2013年的MacBook Pros上仍然须要9s。

BUILD SUCCESSFUL

Total time: 8.674 secs

一个标准的測量时须要多次运行命令。然后去出平均測量结果。由于我们不是在做科学实验,全部跳过这些鼓噪的步骤。带着一粒盐,你的里程可能会发生变化(这句话我也没懂什么意思…)

第二步是在gradle构建时启用分析。去看这些gradle命令你会获取到一份好的日志:

./gradlew :android:assembleDebug --dry-run --profile
open build/reports/profile/profile-2016-02-02-15-39-17.html

这份日志显示,大部分的时间消耗在了配置项目上:



所以让配置更快一些。

1.使用配置需求

有一个降低时间的方法:我们须要尽早的让gradle去配置。幸运的是,这仅仅是另外的一种加入命令标志:

./gradlew :android:assembleDebug --dry-run --profile --configure-on-demand

非常明显,结果好了一些,变成了7s:

BUILD SUCCESSFUL

Total time: 7.144 secs

这个日志显示了在我们调用了这个命令之后降低了2.359s。似乎能够忽略不计。可是换句话来说你就会认为有意义了–这是一个17%的加速了。

配置这样一个命令对gradle是一个孵化的功能,所以它不是默认启用的。或许将来的一天能够默认开启,可是如今我们能够全局使用它。通过在你的home文件夹下加一行.gradle/gradle.properties。

这个命令也满足在linux和OSX系统下:

echo 'org.gradle.configureondemand=true' >> ~/.gradle/gradle.properties

2.使用gradle daemon

如今,由于我们正在谈论全局性,我们也能够使用gradle daemon。gradle daemon是一个后台进程。在gradle构建完毕之前不会退出。下次你能够直接调用gradle,它仍然等待你下次调用。这有非常大意义,由于gradle是一个须要启动的JVM进程。载入JVM。载入class,JIT等等。gradle daemon的作用就是限制全部的开销。

让我们比較一下使用gradle daemon和不适用gradle daemon所消耗的时间:

./gradlew :android:assembleDebug --dry-run --no-daemon
# vs.
./gradlew :android:assembleDebug --dry-run --daemon

在我的机器上,一段时间后,使用gradle daemon要比不适用快的不是一点点:

BUILD SUCCESSFUL

Total time: 2.536 secs

如今仅仅用了2.536s。是不是非常爽?用gradle daemon确实非常棒。所以你应该把它设置成全局的。

echo 'org.gradle.daemon=true' >> ~/.gradle/gradle.properties

3.用最新的gradle版本号

以下我们開始讨论一下gradle的版本号问题。

gradle是一个比較复杂的‘怪物’,大多数的项目随着每一个release版本号越来越快。所以用最新的版本号有非常大意义。

到如今为止最新的gradle版本号是2.2.1,最新的gradle release更新是2.10,。让我们升级用最新的版本号。用不同的构建工具,升级的过程是非常痛苦的。gradle不一样,大多数项目都用的gradle编译,修复gradle版本号确保构建反复性。假设你的项目用gradle编译确实非常棒,而且你也应该用wrapper。比如在他的Virtual JUG session上面,Andres Almiray:JAVA大牛。也是一个gradle粉丝。

相信他,他对gradle的了解不是一点点。

当我们用wrapper的时候,去改变我们正在用的gradle版本号,仅仅须要去更改wrapper配置中的几个数字而已。

这个配置文件在 项目根文件夹gradle/wrapper/gradle-wrapper.properties文件以下。

遗憾的是。由于配置上的一些bug,gradle非常easy失败:

Failed to apply plugin [id ‘com.android.application’]

Gradle version 2.2 is required. Current version is 2.10. If using the gradle wrapper, try editing the distributionUrl in /Users/shelajev/repo/tmp/iosched/gradle/wrapper/gradle-wrapper.properties to gradle-2.2-all.zip

非常显然。这是一个在比較gradle版本号的时候出现的问题。假设用gradle wrapper。试着去改成2.9.然后我们看一下2.9的编译速度:

BUILD SUCCESSFUL

Total time: 1.356 secs

gradle 2.9 果真没让我们失望。从来没这么快过,由之前的8s编程如今的1.3s。

同理也使用与JAVA版本号。假设你还没有升级到JAVA1.8,立即升级吧。

读完这篇文章,立即行动吧。

你还没实用JAVA 8的lambdas.

确保你的构建工具最新。那么你会得到最高效的JAVA版本号运行。

4.优化项目

到如今为止。我们一直在谈编译消耗在构建上。说实话,大部分你能够加速优化的地方在实际的构建过程中隐藏掉了。

好吧,在我们的demo中,我们保存的大部分时间在消除开销。可是我们看看生成项目会发生什么?让我们看一下如何能真正的加速gradle构建。

5.避免繁重的计算

通常情况下,我们能够避免大部分的gradle构建所做的繁重的工作。

让我们看看demo,尝试去降低gradle构建时的IO输出。

比如。你如今构建一个典型的APP为了持续集成,你须要去保存你构建的的一些信息。

这些信息仅仅是一些命令?在你的gradle.build文件里你能够看到:

def cmd = 'git rev-list HEAD --first-parent --count'
def gitVersion = cmd.execute().text.trim().toInteger()
android {
defaultConfig {
versionCode gitVersion
}
}

上面的代码运行一个Git命令。并将结果以供以后使用变量。可是实际上,命令运行须要非常多时间。为了您的开发环境的目的。你可能并不须要这些信息。

幸运的是:gradle真的非常灵活。这些配置仅仅是纯的Groovy文件。所以,假设你改变上面的配置。就像以下的样例一样:

def gitVersion() {
if (!System.getenv('CI_BUILD')) {
// don't care
return 1
}
def cmd = 'git rev-list HEAD --first-parent --count'
cmd.execute().text.trim().toInteger()
}
android {
defaultConfig {
versionCode gitVersion()
}
}

非常轻松避免这种计算,所以你应该注意将上面的代码保存下来。

6.修复依赖

gradle同意你指定项目中依赖包的范围,在以下的样例中。不论什么一个gson 2的小版本号都满足依赖约束。其实。gradle尝试去找最新的版本号,这就消耗了gradle的灵活性。gradle不得不去网上查询哪个版本号可用。这有的是不必要的,尤其假设你的网络环境非常差,像这样:

dependencies {
compile 'com.google.code.gson:gson:2.+'
}

这样不仅会减慢你的项目编译。同一时候也会失去了反复性的构建。

在不论什么的情况下,避免动态依赖和固定版本号号都是一个好方法。这样做不难。仅仅须要找到gradle如今的版本号号而且指定这个数就OK了。

模块化项目和并行化编译

最后,这个并非特别重要,可是或许是最有影响力的,它能提高你的项目编译速度而且使你的项目模块快更好。首先。模块化项目能够并行编译。我们谈论了它如何加快Maven和gradle。并行编译。这是还有一种孵化功能。您须要提供还有一个命令行标志。你也能够给你的gradle命令或者gradle.properties文件里加一个全局的flag

echo 'org.gradle.parallel=true' >> ~/.gradle/gradle.properties

除了明显的加速,它也比多线程构建多了以下几个优点:

1. 并行project的配置

2. 复用之前的项目

3. 项目得到及时检查

4. 在项目编译过程中使用了预编译

最后两点比較重要,它能够及时的非常好的改变你的代码。这意味着gradle能够弄清楚而且能够避免不必要的构建项目。这所做的工作是有史以来最快的工作。

结论

在Madis Pink的讨论中我们看到了几个好的建议。

以下是简短几点:

  • 启用按需配置
  • 用gradle daemon
  • 及时更新新版本号
  • 避免做繁重的计算
  • 不要动态使用依赖
  • 并行编译

当中的一些建议能够降低gradle本身的配置,降低你的项目构建,以及其它相似避免动态依赖和并行的运行。这些将使你的项目构建节省非常多时间。更加让我们开心的是,这些建议相同使用与JAVA项目的构建。

假设你有其它的方法来更快的构建gradle,我更加开心。

记得把那些建议发给我。我会尽我所能来开源这些好的知识。当然你也能够从这篇文章延伸出自己的更好的方法。

到时候记得在Twitter上@我,咱俩能够聊聊。

转自:

http://zeroturnaround.com/rebellabs/making-gradle-builds-faster/.

翻译自:

https://medium.com/@shelajev/6-tips-to-speed-up-your-gradle-build-3d98791d3df9#.2wvd1b2i3

6个技巧加速你的gradle编译的更多相关文章

  1. [转]加速Android Studio/Gradle构建

    加速Android Studio/Gradle构建 android android studio gradle   已经使用Android Studio进行开发超过一年,随着项目的增大,依赖库的增多, ...

  2. Android提升Gradle编译速度或减少Gradle编译时间.md

    目录 Android如何提升Gradle编译速度或减少Gradle编译时间 最终优化方案 优化效果比对 将所有项目源码,各种缓存临时目录都移动到高性能SSD磁盘上 gradle.properties ...

  3. 解决Gradle编译时出现: 编码GBK的不可映射字符

    解决Gradle编译时出现: 编码GBK的不可映射字符 在build.gradle文件中加入如下内容: [compileJava, compileTestJava]*.options*.encodin ...

  4. 深入理解gradle编译-Android基础篇

    深入理解gradle编译-Android基础篇 导读 Gradle基于Groovy的特定领域语言(DSL)编写的一种自动化建构工具,Groovy作为一种高级语言由Java代码实现,本文将对Gradle ...

  5. 加速Android Studio/Gradle构建

    已经使用Android Studio进行开发超过一年,随着项目的增大,依赖库的增多,构建速度越来越慢,现在最慢要6分钟才能build一个release的安装包,在网上查找资料,发现可以通过一些配置可以 ...

  6. 第三篇:gradle 编译 Android app 概览

    引言:经过上两篇的论述,我们已经从代码到架构都简单的熟悉了一遍,理论上,只要知道android app的编译过程,我们大可以自己写一份用gradle编译app的插件,插件内将将整个流程用Task的依赖 ...

  7. 使用 Gradle 编译 Java 项目时报错: Could not find Tools.jar

    在使用Android studio进行编译成jar的时候,遇到Gradle 编译错误,听前辈们说是jdk的版本不对,于是乎就更新了一下jdk, 然而可能是我重新安装jdk的时候改变了安装路径, 在pr ...

  8. android - gradle编译错误 exit value 1,2,3总结

    在使用jenkins,使用gradle编译的时候总会出现一些问题,下面是几个常见问题的解决方法. 被编译的代码或资源有问题( finished with non-zero exit value 1): ...

  9. maven常见问题处理(3-3)Gradle编译时下载依赖失败解决方法

    Gradle编译时在本地仓库中如果没有发现依赖,就会从远程仓库中下载, 默认的远程仓库为 mavenCentral(),即 http://repo1.maven.org/maven2/往往访问速度特别 ...

随机推荐

  1. Linxu基本指令

    一.Linux权限的概念 Linux下有两种用户:普通用户和超级用户(). 普通用户:在linux下做有限的事情: 超级用户:可以在linux系统下做任何事情,不受限制. 普通用户的提示符是“$”,超 ...

  2. vector迭代器

    https://www.cnblogs.com/quant-lee/p/6618829.html

  3. 关于Python的装饰器

    false 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {m ...

  4. HDU-2204- Eddy’s爱好 (容斥原理)

    题意 给出一个数n,问1-n中有多少个数可以表示为m^k,m,k均为正整数且k>1 (1<=n<=1^18) 题解 (一开始^以为是异或懵逼了好久....) 额,显然1这个数比较讨厌 ...

  5. 做一个可复用的 echarts-vue 组件(延迟动画加载)

    在 vue 项目使用 echarts 的场景中,以下三点不容忽视:1. 可视化的数据往往是异步加载的:2. 若一个页面存在大量的图表( 尤其当存在关系图和地图时 ),往往会导致该页面的渲染速度很慢并可 ...

  6. 紫书 习题8-6 UVa 1611 (构造法)

    这道题和例题8-1相当的像. 例题8-1https://blog.csdn.net/qq_34416123/article/details/80112017 一开始我还以为用归并的思想, 用交换把局部 ...

  7. __weak修饰符

    前言 在 HAL 库中,很多回调函数前面使用__weak 修饰符. weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”. 加上了__weak ...

  8. Tomcat连HBase报错: HTTP Status 500 - java.lang.AbstractMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext

    Tomcat中连接HBase数据库,启动的时候报错: HTTP Status 500 - java.lang.AbstractMethodError: javax.servlet.jsp.JspFac ...

  9. [MST] Create an Entry Form to Add Models to the State Tree

    It is time to add new entries to the wishlist. We will achieve this by reusing forms and models we'v ...

  10. 在java项目中怎样利用Dom4j解析XML文件获取数据

    在曾经的学习.net时常常会遇到利用配置文件来解决项目中一些须要常常变换的数据.比方数据库的连接字符串儿等.这个时候在读取配置文件的时候.我们一般会用到一个雷configuration,通过这个类来进 ...