Skip to content

コンパイル時間を改善するためのヒント

Kotlin/Nativeコンパイラは、パフォーマンスを向上させるためのアップデートを継続的に受け取っています。最新のKotlin/Nativeコンパイラを使用し、ビルド環境を適切に設定することで、Kotlin/Nativeターゲットを持つプロジェクトのコンパイル時間を大幅に短縮できます。

Kotlin/Nativeのコンパイルプロセスを高速化するためのヒントを以下に示します。

一般的な推奨事項

最新バージョンのKotlinを使用する

これにより、常に最新のパフォーマンス改善を享受できます。最新のKotlinバージョンは 2.3.0 です。

巨大なクラスの作成を避ける

実行時のコンパイルやロードに時間がかかる巨大なクラスの作成は避けてください。

ダウンロードおよびキャッシュされたコンポーネントをビルド間で保持する

プロジェクトをコンパイルする際、Kotlin/Nativeは必要なコンポーネントをダウンロードし、作業結果の一部を $USER_HOME/.konan ディレクトリにキャッシュします。コンパイラは次回のコンパイルでこのディレクトリを使用し、完了までの時間を短縮します。

コンテナ(Dockerなど)や継続的インテグレーション(CI)システムでビルドする場合、コンパイラはビルドごとに ~/.konan ディレクトリを一から作成しなければならないことがあります。このステップを避けるために、ビルド間で ~/.konan が保持されるように環境を構成してください。例えば、konan.data.dir Gradleプロパティを使用して、その場所を再定義します。

あるいは、cinterop および konanc ツールを介して、-Xkonan-data-dir コンパイラオプションを使用してディレクトリのカスタムパスを構成することもできます。

Gradleの設定

Gradleでの最初のコンパイルは、依存関係のダウンロード、キャッシュの構築、追加のステップの実行が必要になるため、通常、その後のコンパイルよりも時間がかかります。実際のコンパイル時間を正確に把握するには、プロジェクトを少なくとも2回ビルドする必要があります。

コンパイルパフォーマンスを向上させるためのGradle構成の推奨事項を以下に示します。

Gradleのヒープサイズを増やす

Gradleのヒープサイズを増やすには、gradle.properties ファイルに org.gradle.jvmargs=-Xmx3g を追加してください。

並列ビルド(parallel builds)を使用する場合は、org.gradle.workers.max プロパティまたは --max-workers コマンドラインオプションを使用して、適切なワーカー数を選択する必要があるかもしれません。デフォルト値はCPUプロセッサの数です。

必要なバイナリのみをビルドする

本当に必要でない限り、buildassemble などのプロジェクト全体をビルドするGradleタスクを実行しないでください。これらのタスクは同じコードを複数回ビルドするため、コンパイル時間が増加します。IntelliJ IDEAからのテスト実行やXcodeからのアプリ起動などの典型的なケースでは、Kotlinツールは不要なタスクの実行を回避します。

非典型的なケースやビルド構成がある場合は、自分でタスクを選択する必要があるかもしれません。

  • linkDebug*: 開発中にコードを実行する場合、通常はバイナリが1つあれば十分なので、対応する linkDebug* タスクを実行するだけで十分です。

  • embedAndSignAppleFrameworkForXcode: iOSシミュレータとデバイスではプロセッサアーキテクチャが異なるため、Kotlin/Nativeバイナリをユニバーサル(fat)フレームワークとして配布するのが一般的なアプローチです。

    しかし、ローカル開発中は、使用しているプラットフォーム専用の .framework ファイルのみをビルドする方が高速です。プラットフォーム固有のフレームワークをビルドするには、embedAndSignAppleFrameworkForXcode タスクを使用してください。

必要なターゲットのみに対してビルドする

上記の推奨事項と同様に、すべてのネイティブプラットフォーム用のバイナリを一度にビルドしないでください。例えば、XCFramework をコンパイル(*XCFramework タスクを使用)すると、すべてのターゲットに対して同じコードがビルドされるため、単一のターゲットに対してビルドするよりも比例して時間がかかります。

セットアップにXCFrameworkが必要な場合は、ターゲットの数を減らすことができます。例えば、IntelベースのMac上のiOSシミュレータでプロジェクトを実行しないのであれば、iosX64 は必要ありません。

異なるターゲットのバイナリは、linkDebug*$Target および linkRelease*$Target Gradleタスクでビルドされます。 実行されたタスクは、ビルドログ、または --scan オプションを付けてGradleビルドを実行することで Gradleビルドスキャン で確認できます。

不要なリリースバイナリをビルドしない

Kotlin/Nativeは、デバッグとリリースの2つのビルドモードをサポートしています。リリースは高度に最適化されており、これには多くの時間がかかります。リリースバイナリのコンパイルは、デバッグバイナリよりも桁違いに時間がかかります。

実際のリリースを除けば、通常の開発サイクルにおいてこれらすべての最適化は不要かもしれません。開発プロセス中に名前に Release が含まれるタスクを使用している場合は、それを Debug に置き換えることを検討してください。同様に、assembleXCFramework を実行する代わりに、例えば assembleSharedDebugXCFramework を実行できます。

リリースバイナリは linkRelease* Gradleタスクでビルドされます。これらはビルドログ、または --scan オプションを付けてGradleビルドを実行することで Gradleビルドスキャン で確認できます。

Experimental

リリースバイナリのサイズを削減する

リリースバイナリのサイズを削減し、ビルド時間を改善するには、バイナリオプションを有効にする smallBinary を試してください。

これにより、LLVMコンパイルフェーズにおいて、コンパイラのデフォルトの最適化引数として -Oz が実質的に設定されます。このオプションはまだ試験的(Experimental)であり、場合によっては実行時のパフォーマンスに影響を与える可能性があります。

Gradleデーモンを無効にしない

正当な理由がない限り、Gradleデーモンを無効にしないでください。デフォルトでは、Kotlin/NativeはGradleデーモンから実行されます。これが有効な場合、同じJVMプロセスが使用され、コンパイルごとにウォームアップする必要がありません。

推移的エクスポートを使用しない

transitiveExport = true を使用すると、多くの場合でデッドコード削除(dead code elimination)が無効になるため、コンパイラは大量の未使用コードを処理しなければならなくなります。これによりコンパイル時間が増加します。代わりに、必要なプロジェクトや依存関係をエクスポートするには、export メソッドを明示的に使用してください。

モジュールのエクスポートを控えめにする

不要なモジュールのエクスポートは避けてください。エクスポートされた各モジュールは、コンパイル時間とバイナリサイズに悪影響を及ぼします。

Gradleビルドキャッシュを使用する

Gradleのビルドキャッシュ機能を有効にします。

  • ローカルビルドキャッシュ: ローカルキャッシングを行うには、gradle.properties ファイルに org.gradle.caching=true を追加するか、コマンドラインで --build-cache オプションを付けてビルドを実行します。
  • リモートビルドキャッシュ: 継続的インテグレーション環境向けにリモートビルドキャッシュを構成する方法を確認してください。

Gradle構成キャッシュを使用する

Gradleの構成キャッシュ(configuration cache)は、構成フェーズの結果をキャッシュすることでビルドパフォーマンスを向上させます。また、単一プロジェクト内での独立したタスクの並列実行を可能にし、暗黙的に org.gradle.parallel プロパティを有効にして、異なるプロジェクト間のタスクを並列実行できるようにします。

Gradle構成キャッシュを使用するには、gradle.properties ファイルに org.gradle.configuration-cache=true プロパティを追加してください。

構成キャッシュを有効にすると、link* タスクの並列実行も可能になりますが、特にCPUコア数が多いマシンでは負荷が非常に高くなる可能性があります。この問題は KT-70915 で修正される予定です。

以前に無効にした機能を有効にする

Gradleデーモンやコンパイラキャッシュを無効にするKotlin/Nativeオプションがあります。

  • kotlin.native.disableCompilerDaemon=true
  • Gradleビルドファイルの binaries {} ブロックにある disableNativeCache DSL

以前にこれらの機能で問題が発生し、これらの行を gradle.properties ファイルやGradleビルドファイルに追加していた場合は、それらを削除してビルドが正常に完了するか確認してください。これらのプロパティは、すでに修正された問題を回避するために以前に追加されたものである可能性があります。

klibアーティファクトのインクリメンタルコンパイルを試す

インクリメンタルコンパイルを使用すると、プロジェクトモジュールによって生成された klib アーティファクトの一部のみが変更された場合、klib のその部分だけがバイナリに再コンパイルされます。

この機能は試験的(Experimental)です。有効にするには、gradle.properties ファイルに kotlin.incremental.native=true オプションを追加してください。問題が発生した場合は、YouTrackで課題を作成してください。

Windowsの設定

Windows セキュリティが Kotlin/Native コンパイラを低速化させることがあります。デフォルトで %\USERPROFILE% にある .konan ディレクトリを Windows セキュリティの除外リストに追加することで、これを回避できます。Windows セキュリティに除外設定を追加する方法を確認してください。

Advanced

LLVMの設定

上記のヒントでコンパイル時間が改善されない場合は、LLVMバックエンドのカスタマイズを検討してください。