跟踪任务在gradle构建脚本中花费的时间的执行时间最优雅的方法是什么?在最佳情况下,记录与任务名称
直接相同或下一行的时间:buildSrc:testClasses (0.518 secs)
:fooBar (28.652 secs)
答案 0 :(得分:78)
只是详细说明另一个答案:我们想要做同样的事情,以及最后的报告时间 构建,如此缓慢的步骤是显而易见的(当他们放慢构建速度时,适当的各方会感到一点点但又有点健康!)。
BUILD SUCCESSFUL
Total time: 1 mins 37.973 secs
Task timings:
579ms :myproject-foo:clean
15184ms :myproject-bar:clean
2839ms :myproject-bar:compileJava
10157ms :myproject-bar:jar
456ms :myproject-foo:compileJava
391ms :myproject-foo:libs
101ms :myproject-foo:jar
316ms :myproject-bar:compileTestJava
364ms :myproject-foo:compileTestJava
53353ms :myproject-foo:test
2146ms :myproject-bar:test
8348ms :www/node:npmInstall
687ms :www/node:npmTest
可以将下面的代码放入您的顶级build.gradle
,以便在执行期间或完成后报告时间。
// Log timings per task.
class TimingsListener implements TaskExecutionListener, BuildListener {
private Clock clock
private timings = []
@Override
void beforeExecute(Task task) {
clock = new org.gradle.util.Clock()
}
@Override
void afterExecute(Task task, TaskState taskState) {
def ms = clock.timeInMs
timings.add([ms, task.path])
task.project.logger.warn "${task.path} took ${ms}ms"
}
@Override
void buildFinished(BuildResult result) {
println "Task timings:"
for (timing in timings) {
if (timing[0] >= 50) {
printf "%7sms %s\n", timing
}
}
}
@Override
void buildStarted(Gradle gradle) {}
@Override
void projectsEvaluated(Gradle gradle) {}
@Override
void projectsLoaded(Gradle gradle) {}
@Override
void settingsEvaluated(Settings settings) {}
}
gradle.addListener new TimingsListener()
答案 1 :(得分:16)
最干净的解决方案是实现TaskExecutionListener(我确信您可以处理该部分)并将其注册到gradle.taskGraph.addTaskExecutionListener
。
答案 2 :(得分:15)
我知道这是一个老问题,但我找到了一个很酷的插件来完成任务计时。这就像@jlevy一样,但有更多可用选项:https://github.com/passy/build-time-tracker-plugin
Pascal Hartig的这个插件会不断记录您的构建时间并提供CSV和条形图摘要。开发人员推荐它用于监视构建时间,而不是--profile
,它为您提供当前构建的快照。
这就是我目前使用它的方式:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "net.rdrei.android.buildtimetracker:gradle-plugin:0.7.+"
}
}
apply plugin: "build-time-tracker"
buildtimetracker {
reporters {
summary {
ordered false
threshold 50
barstyle 'unicode'
}
}
}
答案 3 :(得分:13)
这是jlevy's answer above的变体,已经过修改,以删除已弃用的可公开访问的gradle Clock
类的使用情况。
BUILD SUCCESSFUL
Total time: 1 mins 37.973 secs
Task timings:
579ms :myproject-foo:clean
15184ms :myproject-bar:clean
2839ms :myproject-bar:compileJava
10157ms :myproject-bar:jar
456ms :myproject-foo:compileJava
391ms :myproject-foo:libs
101ms :myproject-foo:jar
316ms :myproject-bar:compileTestJava
364ms :myproject-foo:compileTestJava
53353ms :myproject-foo:test
2146ms :myproject-bar:test
8348ms :www/node:npmInstall
687ms :www/node:npmTest
可以将下面的代码放入您的顶级build.gradle
,以便在执行期间或完成后报告时间。
import java.util.concurrent.TimeUnit
// Log timings per task.
class TimingsListener implements TaskExecutionListener, BuildListener {
private long startTime
private timings = []
@Override
void beforeExecute(Task task) {
startTime = System.nanoTime()
}
@Override
void afterExecute(Task task, TaskState taskState) {
def ms = TimeUnit.MILLISECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
timings.add([ms, task.path])
task.project.logger.warn "${task.path} took ${ms}ms"
}
@Override
void buildFinished(BuildResult result) {
println "Task timings:"
for (timing in timings) {
if (timing[0] >= 50) {
printf "%7sms %s\n", timing
}
}
}
@Override
void buildStarted(Gradle gradle) {}
@Override
void projectsEvaluated(Gradle gradle) {}
@Override
void projectsLoaded(Gradle gradle) {}
@Override
void settingsEvaluated(Settings settings) {}
}
gradle.addListener new TimingsListener()
答案 4 :(得分:1)
--profile
标志将生成配置文件报告。生成的 HTML 文件包括一个“任务执行”选项卡,其中包含每个任务的计时。
$ gradle build --profile
BUILD SUCCESSFUL in 21s
6 actionable tasks: 6 executed
See the profiling report at: file:///path/to/gs-spring-boot/complete/build/reports/profile/profile-2021-08-09-16-22-40.html
A fine-grained performance profile is available: use the --scan option.
这记录在在线 Command-Line Interface documentation
<块引用>在 $buildDir/reports/profile
目录中生成高级性能报告。 --scan
是首选。
任务 | 持续时间 | 结果 |
---|---|---|
: | 20.046s | (总计) |
:compileJava | 9.221s | |
:测试 | 6.492s | |
:compileTestJava | 3.161s | |
:bootJarMainClassName | 0.813s | |
:bootJar | 0.338s | |
:jar | 0.017s | |
:processResources | 0.003s | 无源 |
:类 | 0.001s | 没有工作 |
:组装 | 0s | 没有工作 |
:构建 | 0s | 没有工作 |
:检查 | 0s | 没有工作 |
:processTestResources | 0s | 无源 |
:testClasses | 0s | 没有工作 |
--profile
选项及其文档均建议使用 --scan
选项生成 build scan。这会生成扫描并将其发布到 scans.gradle.com。除了将您的构建详细信息传输到 Gradle 构建扫描外部服务之外,这还需要接受 Gradle Terms of Service。
$ gradle build --scan
BUILD SUCCESSFUL in 0s
7 actionable tasks: 7 executed
Publishing a build scan to scans.gradle.com requires accepting the Gradle Terms of Service defined at https://gradle.com/terms-of-service.
Do you accept these terms? [yes, no] yes
Gradle Terms of Service accepted.
Publishing build scan...
https://gradle.com/s/5u4w3gxeurtd2
7 秒内在 4 个项目中执行 61 个任务,其中 10 个避免任务节省了 4.231 秒
:buildSrc:compileKotlin | 3.584s |
:app:test | 0.745s |
:list:test | 0.742s |
:list:compileJava | 0.062s |
:utilities:compileJava | 0.054s |
:app:startScripts | 0.049s |
答案 5 :(得分:0)
简单的排序会让@ jlevy的解决方案变得更好 此外,对于典型的制作应用程序,我认为50ms的阈值太低 我们通常关心超过1秒的任务 project / build.gradle
import java.util.concurrent.TimeUnit
// Log timings per task.
class TimingsListener implements TaskExecutionListener, BuildListener {
private long startTime
private timings = []
@Override
void beforeExecute(Task task) {
startTime = System.nanoTime()
}
@Override
void afterExecute(Task task, TaskState taskState) {
def ms = TimeUnit.MILLISECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS)
timings.add(new Tuple2<Integer, String>(ms, task.path))
task.project.logger.warn "${task.path} took ${ms}ms"
}
@Override
void buildFinished(BuildResult result) {
println "Task timings:"
def tmp = timings.toSorted(new Comparator<Tuple2<Integer, String>>() {
@Override
int compare(Tuple2<Integer, String> o, Tuple2<Integer, String> t1) {
return o.first - t1.first
}
})
for (timing in tmp) {
if (timing.first >= 1000) {
printf "%ss %s\n", timing.first / 1000, timing.second
}
}
}
@Override
void buildStarted(Gradle gradle) {}
@Override
void projectsEvaluated(Gradle gradle) {}
@Override
void projectsLoaded(Gradle gradle) {}
@Override
void settingsEvaluated(Settings settings) {}
}
gradle.addListener new TimingsListener()
终端输出:
BUILD SUCCESSFUL in 14m 33s
948 actionable tasks: 419 executed, 476 from cache, 53 up-to-date
Task timings:
1.036s :cbl-config:mergeMyAppDebugResources
1.187s :express:bundleMyAppDebug
1.199s :country:testMyAppDebugUnitTest
1.214s :core-for-test:extractMyAppDebugAnnotations
1.242s :analytics:testMyAppDebugUnitTest
1.308s :express:extractMyAppDebugAnnotations
1.33s :availability:dataBindingExportBuildInfoMyAppDebug
1.357s :app:transformNativeLibsWithStripDebugSymbolForMyAppDebug
1.405s :hermes:generateMyAppDebugBuildConfig
1.56s :availability:testMyAppDebugUnitTest
1.65s :app:javaPreCompileMyAppDebugUnitTest
1.749s :chat:compileMyAppDebugJavaWithJavac
1.858s :cbl-config-for-test:compileMyAppDebugJavaWithJavac
2.027s :cbl-config:compileMyAppDebugJavaWithJavac
2.056s :analytics-for-test:compileMyAppDebugJavaWithJavac
2.447s :crypto:compileMyAppDebugJavaWithJavac
2.45s :crypto:testMyAppDebugUnitTest
2.47s :chat:javaPreCompileMyAppDebugUnitTest
2.639s :crypto-for-test:dataBindingExportBuildInfoMyAppDebug
2.683s :test-utils:compileMyAppDebugJavaWithJavac
3.056s :crypto:lintMyAppDebug
3.227s :app:transformNativeLibsWithMergeJniLibsForMyAppDebug
3.272s :express:testMyAppDebugUnitTest
3.394s :crypto:mergeMyAppDebugResources
3.426s :core:testMyAppDebugUnitTest
4.299s :multicity:testMyAppDebugUnitTest
4.333s :app:packageMyAppDebug
4.584s :availability-for-test:compileMyAppDebugJavaWithJavac
4.672s :app:transformResourcesWithMergeJavaResForMyAppDebug
4.786s :map:lintMyAppDebug
5.309s :country:lintMyAppDebug
5.332s :job:lintMyAppDebug
5.389s :map:testMyAppDebugUnitTest
6.04s :express:lintMyAppDebug
6.584s :hermes:lintMyAppDebug
6.707s :app:transformClassesWithMultidexlistForMyAppDebug
7.052s :multicity:lintMyAppDebug
8.044s :multicity:compileMyAppDebugJavaWithJavac
8.87s :app:transformDexArchiveWithDexMergerForMyAppDebug
9.371s :uikit:testMyAppDebugUnitTest
9.429s :availability:lintMyAppDebug
13.12s :app:compileMyAppDebugUnitTestKotlin
16.276s :hermes:testMyAppDebugUnitTest
16.898s :chat:testMyAppDebugUnitTest
17.174s :job:testMyAppDebugUnitTest
36.008s :grab-junior:testMyAppDebugUnitTest
96.88s :app:compileMyAppDebugJavaWithJavac
125.693s :app:lintMyAppDebug
145.538s :app:transformClassesWithDexBuilderForMyAppDebug
182.752s :app:testMyAppDebugUnitTest
答案 6 :(得分:0)
我创建了一个插件,因为passy/build-time-tracker-plugin不再得到积极维护。我的也可以打印ASCII条形图,并带有自定义选项。
https://github.com/asarkar/build-time-tracker
== Build time summary ==
:commons:extractIncludeProto | 4.000s | 14% | ████
:commons:compileKotlin | 2.000s | 7% | ██
:commons:compileJava | 6.000s | 21% | ██████
:service-client:compileKotlin | 1.000s | 4% | █
:webapp:compileKotlin | 1.000s | 4% | █
:webapp:dockerBuildImage | 4.000s | 14% | ████
:webapp:dockerPushImage | 4.000s | 14% | ████
答案 7 :(得分:0)
答案 8 :(得分:0)
我尝试使用@Jilevys solution,但在找到类 org.gradle.util.Clock()
时遇到错误我已经对其进行了修改,以使用Java8类。将以下代码放在build.gradle顶部
import java.time.LocalDateTime
class TimingsListener implements TaskExecutionListener, BuildListener {
private LocalDateTime taskStartTime
@Override
void beforeExecute(Task task) {
taskStartTime = LocalDateTime.now();
}
@Override
void afterExecute(Task task, TaskState taskState) {
LocalDateTime taskEndTime = LocalDateTime.now();
def seconds = Duration.between(taskStartTime, taskEndTime).toSeconds();
task.project.logger.warn "${task.path} took ${seconds} seconds."
}
@Override
void buildStarted(Gradle gradle) {
project.logger.warn "Build started on "+LocalDateTime.now()
}
@Override
void settingsEvaluated(Settings settings) {
}
@Override
void projectsLoaded(Gradle gradle) {
}
@Override
void projectsEvaluated(Gradle gradle) {
}
@Override
void buildFinished(BuildResult result) {
project.logger.warn "Build finished on "+LocalDateTime.now()
}
}
gradle.addListener new TimingsListener()
它产生类似于下面给出的输出。
<projectname>:<taskName> took 10 seconds.