Kotlin
A concise multiplatform language developed by JetBrains
Kotlin 빌드 보고서를 소개합니다
Kotlin 1.7.0부터 Kotlin 컴파일러 작업에 대한 빌드 보고서를 만들 수 있습니다. 보고서에는 다양한 컴파일 단계의 시간과 증분 컴파일을 사용할 수 없는 이유가 포함되어 있습니다. 이 기능은 아직 실험적이므로 메트릭 항목은 변경될 수 있습니다.
빌드 보고서는 컴파일러 작업과 관련된 문제를 조사하려는 경우에 유용합니다. Gradle 빌드에 너무 많은 시간이 걸리고 성능 저하의 근본 원인을 이해하기가 매우 어려운 경우를 예로 들 수 있습니다. 또 다른 예로 동일한 프로젝트의 컴파일 시간이 다른 경우를 들 수 있습니다. 어떤 때는 몇 초, 어떤 때는 몇 분이 걸리는 경우이죠.
Kotlin 빌드 보고서는 Gradle 빌드 스캔보다 더 효율적으로 문제를 검사하도록 도와줍니다. 많은 엔지니어들이 Gradle 스캔을 사용하여 빌드 성능을 조사하지만 가장 세분화된 검사 단위는 단일 Gradle 작업입니다.
빌드 보고서를 이용하는 방법
빌드 보고서를 사용하려면 빌드 보고서를 저장할 gradle.properties
의 출력 위치를 선언하세요.
kotlin.build.report.output=file
다음 값(및 그 조합)을 사용할 수 있습니다:
file
은 빌드 보고서를 로컬 파일에 저장합니다. 이 위치는 기본적으로${project_folder}/build/reports/kotlin-build/${project_name}-timestamp.txt
입니다.build_scan
은 빌드 스캔의 사용자 지정 값 섹션에 빌드 보고서를 저장합니다. Gradle Enterprise 플러그인은 사용자 지정 값의 수와 길이를 제한합니다. 이로 인해 대규모 프로젝트를 처리할 때 일부 값이 손실될 수 있습니다.
http
는 HTTP 요청을 사용하여 빌드 보고서를 게시합니다. POST 메서드는 메트릭을 JSON 형식으로 보냅니다. 데이터는 버전마다 다를 수 있습니다. Kotlin 저장소에서 전송된 데이터의 현재 버전을 확인하세요.
HTTP 엔드포인트가 없는 경우 아래 샘플 중 하나를 사용하세요.
- ELK 스택을 기반으로 하는 HTTP 엔드포인트. Elasticsearch 인스턴스를 설치하고 Logstash에 대해 다음 구성을 사용합니다.
- Kotlin 기반 HTTP 엔드포인트. CSV 파일로 다시 컴파일한 경우, 컴파일 시간 및 비증분 컴파일 이유에 대한 정보를 저장합니다.
빌드 보고서를 추가로 설정하려면 gradle.properties
에 대해 다음 옵션을 사용하세요.
빌드 보고서를 읽는 방법
최적화 프로세스는 매우 창의적입니다. 완결된 해결법을 제공하기 어려운 경우가 많으며 각 사례를 개별적으로 검토해야 합니다. 그러나 다음 파이프라인을 사용하면 좋은 결과를 얻을 수 있는 경우가 많습니다.
1. 빌드가 점진적이지 않은 이유를 이해하고 근본적인 문제를 수정합니다.
2. 증분 컴파일에 시간이 너무 많이 걸리는 경우 소스 파일을 재구성하는 것이 좋습니다. 예를 들어, 모든 클래스를 하나의 파일에 압축하지 말고, 모든 최상위 함수를 하나의 파일에 선언하지 마세요.
생성된 빌드 보고서를 살펴보겠습니다. 이 작업을 실행하는 데 거의 40초가 걸렸습니다.
총 Gradle 작업 시간은 작업 실행에서 리스너 알림까지의 시간을 보여줍니다. 작업 액션은 Gradle 작업자에서 컴파일 잡을 예약하는 작업만 나타냅니다. 컴파일 자체는 Gradle 작업자에서 수행됩니다. 컴파일 실행 섹션에서 컴파일 시간을 볼 수 있습니다.
Gradle이 입력 간의 차이를 계산할 수 없기 때문에 이 모듈이 비증분적으로 빌드되었음을 알 수 있습니다. 이는 일반적으로 클린 빌드에서 또는 빌드 스크립트가 일부 변경된 경우에 발생합니다. 증분 컴파일을 사용할 수 없기 때문에 거의 모든 시간이 코드 분석에 소요되었습니다.
컴파일을 증분 처리할 수 없는 가장 일반적인 이유는 다음과 같습니다.
DEP_CHANGE_HISTORY_NO_KNOWN_BUILDS
– 종속 모듈 중 하나가 이전에 컴파일되지 않았거나 해당 기록 파일이 보관되었음을 의미합니다.DEP_CHANGE_HISTORY_IS_NOT_FOUND
– 변경된 종속성 중 하나가 소스 모듈 또는 비 Kotlin 모듈이 아님을 의미합니다.OUT_OF_PROCESS_EXECUTION, IN_PROCESS_EXECUTION
– Kotlin 데몬에서 증분 컴파일을 수행할 수 있음을 의미합니다. 다른 모드에서는 강제로 비증분 빌드가 실행됩니다.
Kotlin의 증분 컴파일에 대한 자세한 내용은 이후 게시물에서 다룰 예정입니다. 다음 블로그 게시물도 기대해 주세요!
JetBrains에서 빌드 보고서를 사용하는 방법
컴파일 시간 감소
Space 프로젝트에 대한 이 빌드 보고서를 살펴보세요. 생성된 큰 소스 파일이 있는 모듈이 있었습니다. 컴파일은 증분이었지만 변경이 있을 때마다 여전히 Kotlin 컴파일러가 큰 소스 파일을 다시 분석해야 했습니다.
이 경우 소스를 재구성하는 것이 좋습니다. 즉, 큰 파일을 분할하고, 서로 다른 파일에 개별 클래스를 배치하고, 큰 클래스는 리팩터링하세요.
성능 회귀 추적
Kotlin 팀은 빌드 보고서를 사용하여 여러 프로젝트의 컴파일을 추적합니다. 우리는 개발자들에게 빌드 보고서에 대한 HTTP 엔드포인트을 활성화하여 전체 빌드 성능을 한 곳에서 볼 수 있게 해달라고 요청했습니다. 예를 들어 Kotlin 또는 Gradle 버전 업데이트 후 성능 회귀를 빠르게 확인하고 오래 실행되는 컴파일을 찾을 수 있습니다.






의견을 남겨주세요
여러분의 인프라에서 빌드 보고서를 사용해 보세요. 의견이 있거나 문제가 발생하거나 개선을 제안하고 싶다면 주저하지 말고 이슈 트래커에 해당 내용을 알려주세요. 감사합니다!
게시물 원문 작성자
Subscribe to Kotlin Blog updates
Discover more
隆重推出 Kotlin 构建报告
从 Kotlin 1.7.0 开始,您可以为 Kotlin 编译器任务创建构建报告。 报告包含不同编译阶段的持续时间以及无法使用增量编译的原因。 此功能目前仍为实验性功能,因此指标列表未来可能会发生变化。
想要调查编译器任务的问题时,构建报告就可以派上用场。 例如,当 Gradle 构建花费过多时间时,难以理解性能不佳的根本原因。 或者,相同项目的编译时间不同:有时需要几秒钟,有时需要几分钟。
Kotlin 构建报告能够比 Gradle 构建扫描更有效地展示问题。 许多工程师使用它们来调查构建性能,但 Gradle 扫描中的粒度单位是单个 Gradle 任务。
如何启用构建报告
要启用构建报告,首先在 gradle.properties
中声明保存构建报告的输出位置:
kotlin.build.report.output=file
以下值(及其组合)可用:
file
,将构建报告保存到本地文件中。 默认文件为${project_folder}/build/reports/kotlin-build/${project_name}-timestamp.txt
。build_scan
,将构建报告保存到构建扫描的自定义值部分中。 请注意,Gradle Enterprise 插件会限制自定义值的数量及其长度。 这可能导致处理大型项目时丢失某些值。http
,使用 HTTP(S) 请求发布构建报告。 POST 方法以 JSON 格式发送指标。 数据可能因版本而异,请在 Kotlin 仓库中查看已发送数据的当前版本。
如果您没有 HTTP 端点,请使用以下示例之一:
- 基于 ELK 堆栈的 HTTP 端点。 安装 Elasticsearch 实例并为 Logstash 使用以下配置:
- 基于 Kotlin 的 HTTP 端点。 如果重新编译为 CSV 文件,它将保存编译时长和非增量编译原因的相关信息。
要进一步设置构建报告,请为 gradle.properties
使用以下选项:
如何阅读构建报告
这里的优化过程很有创意。 现成指南经常很难提供,您需要具体情况具体分析。 但有时,您可以使用以下管道获得良好结果:
1. 了解构建并非增量的原因并修正底层问题。
2. 如果增量编译需要过多时间,可以重新组织源代码文件。 例如,不将所有类打包在一个文件中,不将所有顶级函数声明在一个文件中,等等。
我们来看一看生成的构建报告。 执行这个任务花费了将近 40 秒:
Total Gradle 任务时间显示了从任务执行到侦听器通知的时间。 任务操作仅指示在 Gradle 工作进程中安排编译作业的任务。 编译本身在 Gradle 工作进程中执行。 您可以在运行编译部分查看其编译时间。
我们看到这个模块是以非增量方式构建的,因为 Gradle 无法计算输入之间的差异。 这通常发生在干净构建中或在构建脚本中执行了更改时。 由于增量编译不可用,几乎所有时间都花在了代码分析上。
编译无法增量的最常见原因:
DEP_CHANGE_HISTORY_NO_KNOWN_BUILDS
– 这表示先前没有编译某个依赖模块,或者其历史记录文件已被保管起来。DEP_CHANGE_HISTORY_IS_NOT_FOUND
– 这表示某个更改的依赖项不是源模块或非 Kotlin 模块。OUT_OF_PROCESS_EXECUTION, IN_PROCESS_EXECUTION
– 这表示增量编译可在 Kotlin 守护进程中执行。 其他模式都会强制进行非增量构建。
后续文章将发布关于 Kotlin 增量编译的更多详细信息。 敬请关注!
我们如何在 JetBrains 中使用构建报告
减少编译时间
以 Space 项目的这个构建报告为例。 我们有一个包含大量生成的源代码文件的模块。 虽然编译是增量的,但 Kotlin 编译器仍然必须在每次更改时重新分析大型源代码文件。
在这种情况下,建议的做法是重新组织源代码:例如拆分大型文件、将不同的类置于不同的文件中、重构大型类等。
跟踪性能回归
Kotlin 团队使用构建报告跟踪多个项目的编译。 我们让开发者为构建报告启用 HTTP 端点,以在一个位置查看总体构建性能。 例如,您可以在 Kotlin 或 Gradle 版本更新后快速检查性能回归并找到运行时间长的编译。






分享反馈
欢迎在您的基础架构中试用构建报告。 如果您有任何反馈、遇到问题或想提出改进建议,请随时在我们的问题跟踪器中报告。 谢谢!
本博文英文原作者: