近期我们都在讨论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. indexedDB介绍

    什么是 indexedDB IndexedDB 是一种使用浏览器存储大量数据的方法.它创造的数据可以被查询,并且可以离线使用. IndexedDB对于那些需要存储大量数据,或者是需要离线使用的程序是非 ...

  2. BZOJ 1594 [Usaco2008 Jan]猜数游戏(线段数)

    1594: [Usaco2008 Jan]猜数游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 626  Solved: 260[Submit][S ...

  3. C++虚函数与纯虚函数用法与区别

    1. 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class) ...

  4. Android学习路线(十二)Activity生命周期——启动一个Activity

    DEMO下载地址:http://download.csdn.net/detail/sweetvvck/7728735 不像其他的编程模式那样应用是通过main()函数启动的.Android系统通过调用 ...

  5. 纳德拉再造微软:市值如何重回第一阵营(思维确实变了,不再是以windows为中心,拥抱其它各种平台,敢在主战场之外找到适合自己的新战场)

    有人说,现在的美国硅谷充满了“咖喱味”.也有人说,硅谷已经变成“印度谷”.原因就在于,以微软CEO萨提亚·纳德拉.谷歌CEO桑达尔·皮查伊为代表的印度人,近年以来掌控了全世界最令人望而生畏的科技巨头. ...

  6. 用LogParser分析Windows日志

    用LogParser分析Windows日志 实战案例分享 假设你已具有上面的基础知识,那么以下为你准备了更加深入的应用操作视频(从安装到使用的全程记录): http://www.tudou.com/p ...

  7. POJ 3187 全排列+杨辉三角(组合数)

    思路: next_permutation()加个递推组合数随便搞搞就A了- //By SiriusRen #include <cstdio> #include <algorithm& ...

  8. Metasploit的攻击实例讲解----辅助扫描工具

    不多说,直接上干货! 怎么弹出来这个呢,连续按两次tab. msf > use auxiliary/scanner/ Display all possibilities? (y or n) us ...

  9. HD-ACM算法专攻系列(3)——Least Common Multiple

    题目描述: 源码: /**/ #include"iostream" using namespace std; int MinComMultiple(int n, int m) { ...

  10. ListView中嵌套GridView点击事件

    做一个项目时,需要在ListView中嵌套GridView,因为ListView的每个条目中不一定出现GridView,那么问题来了,添加GridView的Item的点击事件后,有GridView出现 ...