inline関数:ラムダのオーバーヘッドをなくす
関数をinlineとしてマークし、ラムダパラメータのオブジェクト生成を回避します。
「inline関数:ラムダのオーバーヘッドをなくす」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
inline関数とは
通常、関数に渡されたラムダは匿名クラスにコンパイルされます。呼び出すたびに新しいオブジェクトが割り当てられるため、メモリと時間が必要です。inlineキーワードを指定すると、コンパイラーは関数本体(およびラムダ引数)を呼び出し箇所に直接コピーします。
inlineの宣言
funの前にinline修飾子を追加します。
inline fun measureTime(block: () -> Unit): Long {
val start = System.nanoTime()
block()
return System.nanoTime() - start
}コンパイラーによる呼び出しの書き換え
measureTime { doWork() }のような呼び出しは、バイトコードレベルではmeasureTimeの本体がインライン展開された形になります。ラムダオブジェクトが割り当てられることはありません。
inlineを使う場面
次のような場合にinlineを使用します。
- 1つ以上のラムダパラメーターを受け取る関数
- 頻繁に呼び出されるホットパス(タイトなループやコンポーザブル)で使う関数
reified型パラメーターが必要な場合(次で説明します)
パフォーマンスベンチマークの例
inlineを使わない場合、高階関数を呼び出すたびにラムダオブジェクトが割り当てられます。使う場合、JVMからは直線的なコードとして見えるため、割り当ても仮想ディスパッチも発生しません。
inline fun repeat(n: Int, block: () -> Unit) {
for (i in 0 until n) block()
}非ローカルリターン
inline関数の重要な利点の1つは、ラムダ内のreturnでラムダだけでなく外側の関数からも抜けられることです。これを非ローカルリターンと呼びます。
inline fun forEach(list: List<Int>, block: (Int) -> Unit) {
for (item in list) block(item)
}
fun findFirst(list: List<Int>): Int {
forEach(list) { if (it > 5) return it } // returns from findFirst
return -1
}inlineの制限
inline関数は実行時に第一級のエンティティとして存在しないため、変数に格納したりオブジェクトとして渡したりできません。fがそのシグネチャの関数参照を想定している場合、f(::measureTime)を呼び出すことはできません。
コレクションパイプラインのインライン展開
標準ライブラリのmap、filter、forEachなどの関数はすべてinlineです。そのため、これらをチェーンしても要素ごとに追加のクロージャオブジェクトが作成されません。
val result = (1..1_000_000)
.filter { it % 2 == 0 } // inline
.map { it * it } // inline
.take(10)コードサイズとのトレードオフ
各呼び出し箇所には、インライン展開されたコードのコピーが配置されます。関数本体が大きく、多くの場所から呼び出されると、バイトコードのサイズが増加します。小さく、頻繁に呼び出されるラムダにはinlineを使用するのが適しています。
companionおよびトップレベルとの関係
inlineはトップレベル関数とメンバー関数に使用できます。プロパティやコンストラクターには使用できません。関数は呼び出し箇所から見える必要があります(通常はpublicまたはinternalです)。
標準ライブラリの例
すでに知っているinline関数には、let、run、apply、also、with、use、synchronized、lazy(ブロック版)があります。これらのラムダをコストなしで実行できるのは、inline修飾子によるものです。
確認問題
高階関数にinlineを指定する主な利点は何ですか。
まとめ:inline関数
重要なポイント:
inlineはラムダオブジェクトの割り当てをなくします- ラムダからの非ローカルリターンを可能にします
reified型パラメーターに必要です- 小さく、頻繁に呼び出される高階関数に適しています
- 標準ライブラリのスコープ関数はすべて
inlineです
よくある質問
「inline関数:ラムダのオーバーヘッドをなくす」レッスンは無料ですか?
はい。「inline関数:ラムダのオーバーヘッドをなくす」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「inline関数:ラムダのオーバーヘッドをなくす」で何を学びますか?
関数をinlineとしてマークし、ラムダパラメータのオブジェクト生成を回避します。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「inline関数:ラムダのオーバーヘッドをなくす」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- inline関数:ラムダのオーバーヘッドをなくす
- noinlineとcrossinline修飾子
- reified型パラメータ:実行時にTへアクセスする
- 実践的なreifiedパターン:パース、DI、シリアライゼーション