Kotlin Gradleプラグインにおけるコンパイルとキャッシュ
このページでは、以下のトピックについて学ぶことができます。
- インクリメンタルコンパイル
- Gradleビルドキャッシュのサポート
- Gradleコンフィグレーションキャッシュのサポート
- KotlinデーモンとGradleでの使用方法
- 以前のコンパイラへのロールバック
- Kotlinコンパイラの実行戦略の定義
- Kotlinコンパイラのフォールバック戦略
- 最新の言語バージョンの試用
- ビルドレポート
インクリメンタルコンパイル
Kotlin Gradleプラグインはインクリメンタルコンパイルをサポートしており、Kotlin/JVMおよびKotlin/JSプロジェクトではデフォルトで有効になっています。 インクリメンタルコンパイルは、ビルド間のクラスパス内のファイルの変更を追跡し、これらの変更によって影響を受けるファイルのみがコンパイルされるようにします。 このアプローチは、Gradleのビルドキャッシュと連携し、コンパイル回避をサポートします。
Kotlin/JVMの場合、インクリメンタルコンパイルはクラスパスのスナップショットに依存しています。 これは、モジュールのAPI構造をキャプチャし、いつ再コンパイルが必要かを判断します。 全体のパイプラインを最適化するために、Kotlinコンパイラは2種類のクラスパススナップショットを使用します。
- 詳細スナップショット (Fine-grained snapshots):プロパティや関数など、クラスメンバーに関する詳細情報を含みます。 メンバーレベルの変更が検出されると、Kotlinコンパイラは変更されたメンバーに依存するクラスのみを再コンパイルします。 パフォーマンスを維持するために、Kotlin GradleプラグインはGradleキャッシュ内の
.jar
ファイルに対して粗粒度スナップショットを作成します。 - 粗粒度スナップショット (Coarse-grained snapshots):クラスのABIハッシュのみを含みます。 ABIの一部が変更された場合、Kotlinコンパイラは変更されたクラスに依存するすべてのクラスを再コンパイルします。 これは、外部ライブラリのように頻繁に変更されないクラスに役立ちます。
NOTE
Kotlin/JSプロジェクトは、履歴ファイルに基づく異なるインクリメンタルコンパイルアプローチを使用します。
インクリメンタルコンパイルを無効にする方法はいくつかあります。
Kotlin/JVMでは
kotlin.incremental=false
を設定します。Kotlin/JSプロジェクトでは
kotlin.incremental.js=false
を設定します。コマンドラインパラメータとして
-Pkotlin.incremental=false
または-Pkotlin.incremental.js=false
を使用します。このパラメータは、以降の各ビルドに追加する必要があります。
インクリメンタルコンパイルを無効にすると、ビルド後にインクリメンタルキャッシュが無効になります。最初のビルドは決してインクリメンタルではありません。
TIP
インクリメンタルコンパイルの問題は、エラー発生から数回後のビルドで初めて顕在化することがあります。ビルドレポートを使用して
変更とコンパイルの履歴を追跡してください。これは、再現可能なバグ報告の提供に役立ちます。
現在のインクリメンタルコンパイルのアプローチがどのように機能し、以前のアプローチと比較してどうかについて詳しく知るには、ブログ投稿をご覧ください。
Gradleビルドキャッシュのサポート
Kotlinプラグインは、Gradleビルドキャッシュを使用します。これは、将来のビルドで再利用するために ビルド出力を保存します。
すべてのKotlinタスクでキャッシュを無効にするには、システムプロパティkotlin.caching.enabled
をfalse
に設定します(ビルドを引数-Dkotlin.caching.enabled=false
で実行します)。
Gradleコンフィグレーションキャッシュのサポート
Kotlinプラグインは、Gradleコンフィグレーションキャッシュを使用します。これは、以降のビルドで設定フェーズの結果を再利用することで、ビルドプロセスを高速化します。
コンフィグレーションキャッシュを有効にする方法については、Gradleドキュメントを参照してください。この機能を有効にすると、Kotlin Gradleプラグインは自動的にそれを使用し始めます。
KotlinデーモンとGradleでの使用方法
Kotlinデーモンは以下の機能を提供します。
- Gradleデーモンと一緒に実行され、プロジェクトをコンパイルします。
- IntelliJ IDEAの内蔵ビルドシステムでプロジェクトをコンパイルする場合、Gradleデーモンとは別に実行されます。
Kotlinデーモンは、Kotlinコンパイルタスクのいずれかがソースのコンパイルを開始するときに、Gradleの実行段階で起動します。 Kotlinデーモンは、Gradleデーモンと一緒に停止するか、Kotlinのコンパイルが2時間アイドル状態が続いた後に停止します。
Kotlinデーモンは、Gradleデーモンと同じJDKを使用します。
KotlinデーモンのJVM引数の設定
次のいずれかの方法で引数を設定すると、それ以前に設定された引数が上書きされます。
Gradleデーモン引数の継承
デフォルトでは、KotlinデーモンはGradleデーモンから特定の引数セットを継承しますが、Kotlinデーモンに直接指定されたJVM引数によってそれらを上書きします。例えば、gradle.properties
ファイルに以下のJVM引数を追加した場合:
org.gradle.jvmargs=-Xmx1500m -Xms500m -XX:MaxMetaspaceSize=1g
これらの引数はKotlinデーモンのJVM引数に追加されます。
-Xmx1500m -XX:ReservedCodeCacheSize=320m -XX:MaxMetaspaceSize=1g -XX:UseParallelGC -ea -XX:+UseCodeCacheFlushing -XX:+HeapDumpOnOutOfMemoryError -Djava.awt.headless=true -Djava.rmi.server.hostname=127.0.0.1 --add-exports=java.base/sun.nio.ch=ALL-UNNAMED
NOTE
KotlinデーモンのJVM引数に関するデフォルトの動作について詳しく知るには、KotlinデーモンのJVM引数に関する動作をご覧ください。
kotlin.daemon.jvm.optionsシステムプロパティ
GradleデーモンのJVM引数にkotlin.daemon.jvm.options
システムプロパティが含まれている場合、gradle.properties
ファイルでそれを使用します。
org.gradle.jvmargs=-Dkotlin.daemon.jvm.options=-Xmx1500m,Xms500m
引数を渡す際には、以下のルールに従ってください。
Xmx
、XX:MaxMetaspaceSize
、XX:ReservedCodeCacheSize
の引数のみ、前にハイフン-
を使用します。- 引数はスペースを_入れずに_カンマ
,
で区切ります。スペースの後に続く引数はKotlinデーモンではなく、Gradleデーモンで使用されます。
DANGER
以下のすべての条件が満たされている場合、Gradleはこれらのプロパティを無視します。
GradleがJDK 1.9以上を使用している。
Gradleのバージョンが7.0から7.1.1(両端を含む)の間である。
GradleがKotlin DSLスクリプトをコンパイルしている。
Kotlinデーモンが実行されていない。
これを回避するには、Gradleをバージョン7.2(またはそれ以上)にアップグレードするか、次のセクションで説明するkotlin.daemon.jvmargs
プロパティを使用してください。
kotlin.daemon.jvmargsプロパティ
gradle.properties
ファイルにkotlin.daemon.jvmargs
プロパティを追加できます。
kotlin.daemon.jvmargs=-Xmx1500m -Xms500m
ここで、またはGradleのJVM引数でReservedCodeCacheSize
引数を指定しない場合、Kotlin Gradleプラグインはデフォルト値の320m
を適用することに注意してください。
-Xmx1500m -XX:ReservedCodeCacheSize=320m -Xms500m
kotlinエクステンション
kotlin
エクステンションで引数を指定できます。
kotlin {
kotlinDaemonJvmArgs = listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC")
}
kotlin {
kotlinDaemonJvmArgs = ["-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"]
}
特定のタスク定義
特定のタスクの引数を指定できます。
tasks.withType<CompileUsingKotlinDaemon>().configureEach {
kotlinDaemonJvmArguments.set(listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"))
}
tasks.withType(CompileUsingKotlinDaemon).configureEach { task ->
task.kotlinDaemonJvmArguments = ["-Xmx1g", "-Xms512m"]
}
NOTE
この場合、タスク実行時に新しいKotlinデーモンインスタンスが起動する可能性があります。KotlinデーモンのJVM引数に関する動作について詳しく学びましょう。
KotlinデーモンのJVM引数に関する動作
KotlinデーモンのJVM引数を設定する際は、以下の点に注意してください。
- 異なるサブプロジェクトやタスクが異なるJVM引数セットを持つ場合、複数のKotlinデーモンインスタンスが同時に実行されることが想定されます。
- 新しいKotlinデーモンインスタンスは、Gradleが関連するコンパイルタスクを実行し、既存のKotlinデーモンが同じJVM引数セットを持たない場合にのみ起動します。 プロジェクトに多数のサブプロジェクトがあるとします。ほとんどのサブプロジェクトはKotlinデーモンのためのヒープメモリを少量しか必要としませんが、1つのモジュールは大量のヒープメモリを必要とします(ただし、コンパイルされることはめったにありません)。 この場合、そのモジュールには異なるJVM引数セットを提供すべきです。これにより、より大きなヒープサイズを持つKotlinデーモンは、この特定のモジュールを触る開発者に対してのみ起動します。
NOTE
もし、コンパイル要求を処理するのに十分なヒープサイズを持つKotlinデーモンがすでに実行されている場合、 他の要求されたJVM引数が異なっていても、新しいデーモンを起動する代わりにこのデーモンが再利用されます。
以下の引数が指定されていない場合、KotlinデーモンはそれらをGradleデーモンから継承します。
-Xmx
-XX:MaxMetaspaceSize
-XX:ReservedCodeCacheSize
。指定されていないか継承されていない場合、デフォルト値は320m
です。
Kotlinデーモンには、以下のデフォルトJVM引数が設定されています。
-XX:UseParallelGC
。この引数は、他のガベージコレクタが指定されていない場合にのみ適用されます。-ea
-XX:+UseCodeCacheFlushing
-Djava.awt.headless=true
-D{java.servername.property}={localhostip}
--add-exports=java.base/sun.nio.ch=ALL-UNNAMED
。この引数は、JDKバージョン16以上の場合にのみ適用されます。
NOTE
KotlinデーモンのデフォルトJVM引数のリストは、バージョンによって異なる場合があります。実行中のJVMプロセス(Kotlinデーモンなど)の実際の`設定を確認するには、VisualVMのようなツールを使用できます。
以前のコンパイラへのロールバック
Kotlin 2.0.0以降、K2コンパイラがデフォルトで使用されます。
Kotlin 2.0.0以降で以前のコンパイラを使用するには、以下のいずれかを実行します。
build.gradle.kts
ファイルで、言語バージョンを1.9
に設定します。または
以下のコンパイラオプションを使用します:
-language-version 1.9
。
K2コンパイラの利点について詳しくは、K2コンパイラ移行ガイドをご覧ください。
Kotlinコンパイラ実行戦略の定義
_Kotlinコンパイラ実行戦略_は、Kotlinコンパイラがどこで実行されるか、およびそれぞれの場合にインクリメンタルコンパイルがサポートされるかどうかを定義します。
コンパイラ実行戦略には3種類あります。
戦略 | Kotlinコンパイラが実行される場所 | インクリメンタルコンパイル | その他の特徴と注意事項 |
---|---|---|---|
デーモン (Daemon) | 独自のデーモンプロセス内 | はい | _デフォルトかつ最速の戦略_です。異なるGradleデーモンや複数の並行コンパイル間で共有できます。 |
プロセス内 (In process) | Gradleデーモンプロセス内 | いいえ | Gradleデーモンとヒープを共有する場合があります。「プロセス内」実行戦略は「デーモン」実行戦略よりも_低速_です。各ワーカーは、コンパイルごとに個別のKotlinコンパイラのクラスローダーを作成します。 |
プロセス外 (Out of process) | 各コンパイルに対して個別のプロセス内 | いいえ | 最も低速な実行戦略です。「プロセス内」と同様ですが、さらにコンパイルごとにGradleワーカー内で個別のJavaプロセスを作成します。 |
Kotlinコンパイラ実行戦略を定義するには、以下のいずれかのプロパティを使用できます。
kotlin.compiler.execution.strategy
Gradleプロパティ。compilerExecutionStrategy
コンパイルタスクプロパティ。
タスクプロパティcompilerExecutionStrategy
は、Gradleプロパティkotlin.compiler.execution.strategy
よりも優先されます。
kotlin.compiler.execution.strategy
プロパティで利用可能な値は以下の通りです。
daemon
(デフォルト)in-process
out-of-process
gradle.properties
でGradleプロパティkotlin.compiler.execution.strategy
を使用します。
kotlin.compiler.execution.strategy=out-of-process
compilerExecutionStrategy
タスクプロパティで利用可能な値は以下の通りです。
org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy.DAEMON
(デフォルト)org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy.IN_PROCESS
org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy.OUT_OF_PROCESS
ビルドスクリプトでタスクプロパティcompilerExecutionStrategy
を使用します。
import org.jetbrains.kotlin.gradle.tasks.CompileUsingKotlinDaemon
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy
// ...
tasks.withType<CompileUsingKotlinDaemon>().configureEach {
compilerExecutionStrategy.set(KotlinCompilerExecutionStrategy.IN_PROCESS)
}
import org.jetbrains.kotlin.gradle.tasks.CompileUsingKotlinDaemon
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy
// ...
tasks.withType(CompileUsingKotlinDaemon)
.configureEach {
compilerExecutionStrategy = KotlinCompilerExecutionStrategy.IN_PROCESS
}
Kotlinコンパイラのフォールバック戦略
Kotlinコンパイラのフォールバック戦略は、デーモンが何らかの理由で失敗した場合に、Kotlinデーモンの外でコンパイルを実行することです。 Gradleデーモンがオンの場合、コンパイラは「プロセス内」戦略を使用します。 Gradleデーモンがオフの場合、コンパイラは「プロセス外」戦略を使用します。
このフォールバックが発生すると、Gradleのビルド出力に以下の警告メッセージが表示されます。
Failed to compile with Kotlin daemon: java.lang.RuntimeException: Could not connect to Kotlin compile daemon
[exception stacktrace]
Using fallback strategy: Compile without Kotlin daemon
Try ./gradlew --stop if this issue persists.
しかし、別の戦略へのサイレントフォールバックは、大量のシステムリソースを消費したり、非決定的なビルドにつながる可能性があります。 これについては、このYouTrack issueで詳しく読むことができます。 これを避けるために、kotlin.daemon.useFallbackStrategy
というGradleプロパティがあり、そのデフォルト値はtrue
です。 この値がfalse
の場合、デーモンの起動または通信に問題があるとビルドは失敗します。このプロパティをgradle.properties
で宣言します。
kotlin.daemon.useFallbackStrategy=false
KotlinコンパイルタスクにはuseDaemonFallbackStrategy
プロパティもあり、両方を使用する場合はGradleプロパティよりも優先されます。
tasks {
compileKotlin {
useDaemonFallbackStrategy.set(false)
}
}
tasks.named("compileKotlin").configure {
useDaemonFallbackStrategy = false
}
コンパイルを実行するためのメモリが不足している場合、ログにその旨のメッセージが表示されることがあります。
最新の言語バージョンの試用
Kotlin 2.0.0以降、最新の言語バージョンを試すには、gradle.properties
ファイルでkotlin.experimental.tryNext
プロパティを設定します。このプロパティを使用すると、Kotlin GradleプラグインはKotlinバージョンのデフォルト値よりも1つ上の言語バージョンにインクリメントします。たとえば、Kotlin 2.0.0ではデフォルトの言語バージョンは2.0であるため、このプロパティは言語バージョン2.1を設定します。
または、以下のコマンドを実行することもできます。
./gradlew assemble -Pkotlin.experimental.tryNext=true
ビルドレポートでは、各タスクのコンパイルに使用された言語バージョンを確認できます。
ビルドレポート
ビルドレポートには、異なるコンパイルフェーズの所要時間と、コンパイルがインクリメンタルでなかった理由が含まれています。 コンパイル時間が長すぎる場合や、同じプロジェクトなのに異なる場合に、パフォーマンスの問題を調査するためにビルドレポートを使用してください。
Kotlinビルドレポートは、単位が単一のGradleタスクであるGradleビルドスキャンよりも効率的にビルドパフォーマンスの問題を調査するのに役立ちます。
長時間のコンパイルのビルドレポートを分析することで解決できる一般的なケースが2つあります。
- ビルドがインクリメンタルではなかった。原因を分析し、根本的な問題を修正します。
- ビルドはインクリメンタルだったが、時間がかかりすぎた。ソースファイルの再編成を試みます — 大きなファイルを分割したり、個別のクラスを別のファイルに保存したり、大きなクラスをリファクタリングしたり、トップレベル関数を別のファイルで宣言したりなど。
ビルドレポートは、プロジェクトで使用されているKotlinバージョンも表示します。さらに、Kotlin 1.9.0以降、Gradleビルドスキャンでコードのコンパイルに使用されたコンパイラを確認できます。
ビルドレポートの読み方と、JetBrainsがビルドレポートをどのように使用しているかについて学びましょう。
ビルドレポートの有効化
ビルドレポートを有効にするには、gradle.properties
でビルドレポートの出力先を宣言します。
kotlin.build.report.output=file
出力には以下の値とその組み合わせが利用可能です。
| オプション | 説明 Training:**
- Students will explore various types of models, understand the characteristics of different models, and choose the appropriate models to solve various problems.
- Students will learn how to deal with real-world data, including data collection, cleaning, preprocessing, and feature engineering, to improve the performance of models.
- Students will learn how to evaluate model performance, choose appropriate evaluation metrics, and tune model parameters to achieve optimal performance.
- Students will understand the limitations of models and the importance of interpretability and fairness, and learn how to address these issues.
Prerequisites
- Familiarity with Python programming.
- Basic understanding of linear algebra, calculus, and probability.
Instructor
[Instructor Name]
Course Outline
Week 1: Introduction to Machine Learning
- What is Machine Learning?
- Types of Machine Learning (Supervised, Unsupervised, Reinforcement Learning)
- Applications of Machine Learning
- Machine Learning Workflow
- Setting up your Development Environment (Python, scikit-learn, pandas, numpy, matplotlib, seaborn)
Week 2: Data Preprocessing and Feature Engineering
- Data Collection and Loading
- Handling Missing Values
- Handling Categorical Data
- Feature Scaling (Normalization, Standardization)
- Feature Engineering Techniques (Polynomial Features, Interaction Terms, One-Hot Encoding)
- Dimensionality Reduction (PCA, t-SNE)
Week 3: Supervised Learning - Regression
- Introduction to Regression
- Linear Regression (Simple, Multiple)
- Polynomial Regression
- Ridge, Lasso, and Elastic Net Regression
- Support Vector Regression (SVR)
- Decision Tree Regression
- Ensemble Methods for Regression (Random Forest Regressor, Gradient Boosting Regressor)
- Evaluation Metrics for Regression (MAE, MSE, RMSE, R-squared)
Week 4: Supervised Learning - Classification
- Introduction to Classification
- Logistic Regression
- K-Nearest Neighbors (KNN)
- Support Vector Machines (SVM)
- Decision Tree Classifier
- Ensemble Methods for Classification (Random Forest Classifier, Gradient Boosting Classifier, AdaBoost)
- Evaluation Metrics for Classification (Accuracy, Precision, Recall, F1-score, ROC-AUC)
- Confusion Matrix and Classification Report
Week 5: Unsupervised Learning - Clustering and Association Rules
- Introduction to Unsupervised Learning
- Clustering Algorithms (K-Means, Hierarchical Clustering, DBSCAN)
- Evaluating Clustering Performance (Silhouette Score)
- Introduction to Association Rule Learning
- Apriori Algorithm
Week 6: Model Evaluation and Hyperparameter Tuning
- Cross-validation (K-Fold, Stratified K-Fold)
- Bias-Variance Trade-off
- Overfitting and Underfitting
- Hyperparameter Tuning Techniques (Grid Search, Random Search, Bayesian Optimization)
- Saving and Loading Models
Week 7: Introduction to Deep Learning and Neural Networks
- Introduction to Deep Learning
- Perceptron and Multilayer Perceptron (MLP)
- Activation Functions (ReLU, Sigmoid, Tanh)
- Loss Functions and Optimizers
- Backpropagation
- Building a Simple Neural Network with Keras/TensorFlow
Week 8: Advanced Topics and Model Deployment
- Model Interpretability (LIME, SHAP)
- Fairness in Machine Learning
- Introduction to MLOps
- Model Deployment Strategies (Flask, Docker)
- Ethics in AI
- Case Studies and Project Work
Grading
- Homework Assignments: 40%
- Midterm Project: 30%
- Final Project: 30%
Contact Information
For any questions, please contact [Instructor Email Address].
Note: This course outline is subject to change based on the pace and needs of the students.