gpt4 book ai didi

java - 有没有办法按类跟踪java编译时间?

转载 作者:行者123 更新时间:2023-12-05 06:37:13 26 4
gpt4 key购买 nike

我为一个包含多个 java gradle 模块的项目做出贡献。最近合并了其中两个,这显着增加了编译时间。我读到使用推断泛型和重载方法会增加编译时间。

是否有任何工具可以帮助查找 Java 中编译时间较慢的类?或者指出潜在速度陷阱的 linter?

最佳答案

我一直在寻找一种方法来做同样的事情,并且不得不想出我自己的方法,我将在下面描述。

首先,请注意,当您使用 javac 编译类时,您可以传递 -verbose 标志,以便编译器记录所有发生的事情(它将输出发送到 stderr ).

在 Gradle 中,您可以按如下方式将该选项传递给编译器:

compileJava {
options.verbose = true
}

我的 hello world 类看起来像这样(隐藏了很多不相关的东西):

[parsing started SimpleFileObject[/Users/renato/programming/experiments/java/Main.java]]
[parsing completed 21ms]
[loading /modules/jdk.jsobject/module-info.class]
[loading /modules/jdk.management/module-info.class]

...

[checking Main]
[loading /modules/java.base/java/io/Serializable.class]
[loading /modules/java.base/java/lang/AutoCloseable.class]
[loading /modules/java.base/java/lang/Class.class]
[loading /modules/java.base/java/lang/System.class]
[loading /modules/java.base/java/io/PrintStream.class]
[loading /modules/java.base/java/lang/Appendable.class]
[loading /modules/java.base/java/io/Closeable.class]
[loading /modules/java.base/java/io/FilterOutputStream.class]
[loading /modules/java.base/java/io/OutputStream.class]
[loading /modules/java.base/java/io/Flushable.class]
[wrote Main.class]
[total 229ms]

如您所见,您可以捕获 stderr,然后计算它说 parsing started ...Main.javawrote Main.class 之间花费的时间。

如果您跟踪每个源文件和等效类文件的消息,您应该能够获得有关编译每个类所用时间的准确信息。

不幸的是,我认为 Gradle 不允许我们使用 Java 编译器的输出,因此我们需要使用其他东西来为我们运行 Gradle 并解析该输出。

下面是一个使用 Groovy 脚本执行此操作的示例(即使在 Windows 中进行少量编辑也应该适合您,或者仅使用 javacmvn 进行编译):

def projectDir = new File(System.getProperty('user.home') + '/programming/experiments/gradle')
def javaSourcesRoot = new File(projectDir, 'src/main/java').absolutePath
def classFilesRoot = new File(projectDir, 'build/classes/java/main').absolutePath
def sourcesPrefix = "[parsing started SimpleFileObject[$javaSourcesRoot/"
def donePrefix = "[wrote $classFilesRoot/"

log "Starting Gradle"
def gradle = ['gradle', 'compileJava'].execute((List) null, projectDir)

def stdout = new StringBuilder()
def stderr = new StringBuilder()


gradle.consumeProcessOutput(stdout, stderr)

assert gradle.waitFor() == 0: "$stdout\n$stderr"

def classInfo = [:]

stderr.eachLine { line ->
if (line.startsWith(sourcesPrefix)) {
def className = (line - sourcesPrefix - '.java]]').replaceAll(File.separator, '.')
log "Started compiling class $className"
classInfo[className] = [startTime: System.currentTimeMillis()]
}
if (line.startsWith(donePrefix)) {
def className = (line - donePrefix - '.class]').replaceAll('/', '.')
log "Done compiling class $className"
classInfo[className].endTime = System.currentTimeMillis()
}
}

def results = classInfo.collect { String className, Map info ->
"${className.padRight(20)} ${info.endTime - info.startTime}"
}.join('\n')

log "Results:\n$results"

void log(msg) {
println "${new Date()} - $msg"
}

我的小示例项目的结果:

Fri Jul 23 16:39:18 CEST 2021 - Starting Gradle
Fri Jul 23 16:39:20 CEST 2021 - Started compiling class other.JavaType
Fri Jul 23 16:39:20 CEST 2021 - Started compiling class my.Main
Fri Jul 23 16:39:20 CEST 2021 - Done compiling class other.JavaType
Fri Jul 23 16:39:20 CEST 2021 - Done compiling class my.Main
Fri Jul 23 16:39:20 CEST 2021 - Results:
other.JavaType 9
my.Main 4

时间以毫秒为单位,所以 my.Main,一个 hello world 类,用了 9ms 编译... other.JavaType 是一个空类,用了 4ms。

关于java - 有没有办法按类跟踪java编译时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48102396/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com