Gradle 提供了多种检查构建的方法

  • 使用构建扫描进行性能分析

  • 本地性能报告

  • 低级别性能分析

什么是构建扫描?

构建扫描是运行构建时发生情况的持久、可共享的记录。构建扫描提供对构建的深入了解,您可以使用这些信息来识别和修复性能瓶颈。

在 Gradle 4.3 及更高版本中,您可以使用 --scan 命令行选项创建构建扫描

$ gradle build --scan

对于较旧的 Gradle 版本,构建扫描插件用户手册 解释了如何启用构建扫描。

在构建结束时,Gradle 会显示一个 URL,您可以在其中找到构建扫描

BUILD SUCCESSFUL in 2s
4 actionable tasks: 4 executed

Publishing build scan...
https://gradle.com/s/e6ircx2wjbf7e

本节介绍如何使用构建扫描分析构建性能。

使用构建扫描进行性能分析

性能页面可以帮助您使用构建扫描来分析构建性能。要访问该页面,请单击左侧导航菜单中的“Performance”,或单击构建扫描主页上的“Explore performance”链接

build scan home
图 1. 构建扫描主页上的性能页面链接

性能页面显示完成构建的不同阶段所花费的时间。此页面显示了以下操作所花费的时间

  • 启动

  • 配置构建的项目

  • 解析依赖

  • 执行 Task

您还可以获得有关环境属性的详细信息,例如是否使用了守护进程。

build scan performance page
图 2. 构建扫描性能页面

在上面的构建扫描中,配置花费了超过 13 秒。单击“Configuration”选项卡,将此阶段分解为组件部分,从而揭示速度缓慢的原因。

build scan configuration breakdown
图 3. 构建扫描配置分解

在这里,您可以看到应用于项目的脚本和插件,按应用时间降序排列。最慢的插件和脚本应用程序是优化的良好候选对象。例如,脚本 script-b.gradle 应用了一次,但花费了 3 秒。展开该行以查看构建在何处应用了此脚本。

script b application
图 4. 显示 script-b.gradle 应用于构建

您可以看到子项目 :app1 从该子项目的 build.gradle 文件内部应用了该脚本一次。

性能报告

如果您不想使用构建扫描,可以在根项目的 build/reports/profile 目录中生成 HTML 报告。要生成此报告,请使用 --profile 命令行选项

$ gradle --profile <tasks>

每个性能报告的名称中都有一个时间戳,以避免覆盖现有报告。

该报告显示了运行构建所花费时间的分解。但是,此分解不如构建扫描详细。以下性能报告显示了可用的不同类别

Sample Gradle profile report
图 5. 性能报告示例

低级别性能分析

有时,即使构建脚本做的一切都正确,构建也可能很慢。这通常归结为插件和自定义 Task 中的效率低下或资源受限。使用 Gradle Profiler 查找这些瓶颈。使用 Gradle Profiler,您可以定义诸如“在进行 ABI 破坏性更改后运行 'assemble'”之类的场景,并多次运行构建以收集性能分析数据。使用 Profiler 生成构建扫描。或将其与 JProfiler 和 YourKit 等方法分析器结合使用。这些分析器可以帮助您在自定义插件中找到低效的算法。如果您发现 Gradle 本身中的某些东西减慢了构建速度,请随时将分析器快照发送至 performance@gradle.com

性能类别

构建扫描和本地性能报告都将构建执行分解为相同的类别。以下部分解释了这些类别。

启动

这反映了 Gradle 的初始化时间,主要包括

  • JVM 初始化和类加载

  • 如果您使用 Gradle Wrapper,则下载 Gradle 发行版

  • 如果合适的守护进程尚未运行,则启动守护进程

  • 执行 Gradle 初始化脚本

即使构建执行的启动时间很长,后续运行通常也会看到启动时间大幅下降。持续缓慢的构建启动时间通常是 init 脚本中出现问题的结果。仔细检查您在那里所做的工作是否必要且性能良好。

Settings 和 buildSrc

启动后,Gradle 会初始化您的项目。通常,Gradle 只处理您的 settings 文件。如果您的 buildSrc 目录中有自定义构建逻辑,Gradle 也会处理该逻辑。构建 buildSrc 一次后,Gradle 会认为它是最新的。最新的检查比逻辑处理花费的时间少得多。如果您的 buildSrc 阶段花费的时间太长,请考虑将其分解为单独的项目。然后,您可以将该项目的 JAR 工件添加为依赖项。

settings 文件很少包含具有大量 I/O 或计算的代码。如果您发现 Gradle 花费很长时间来处理它,请使用更传统的性能分析方法,例如 Gradle Profiler,来确定原因。

加载项目

加载项目通常不会花费大量时间,您也无法控制它。此处花费的时间基本上是您构建中项目数量的函数。