算譜王におれはなる!!!!

偏りはあると思うけど情報技術全般についてマイペースに書くよ。

Kotlin M7でインライン関数がサポートされたよ〜

Kotlin M7公開

本日Kotlin M7が公開されました。

http://blog.jetbrains.com/kotlin/2014/03/m7-release-available

Kotlinプロジェクト開始当初(たぶん)から仕様に盛り込まれていた インライン関数 がついに実装されました!

インライン関数とは

inlineアノテーションが付いた関数で、その呼び出しがコンパイル時にインライン展開されます。呼び出しが高コストである高階関数をインライン関数として定義するとパフォーマンスが改善することがあります。Kotlinの標準ライブラリには既にインライン関数が多く存在します。

試してみた

次のようなコードで実験してみました。

(1..5) forEach {
  println(it)
}

IntRange#forEach*1は、関数オブジェクトを1つ取るインライン関数です。この例では関数リテラル(ラムダ式)として引数に渡しています。M7より前のバージョンだと、この関数リテラルFunction1の無名クラスとしてコンパイルされていました。しかし今では新たにクラスを作ってnewするなんてことはありません。インライン関数のおかげで次のようなコードとしてコンパイルされます。

for (element in (1..5)) {
  println(element)
}

実際、コンパイルして得られたclassファイルを覗くとこんな感じになっています。

普通の関数にinline付けると警告が出る

関数オブジェクトを引数に取らない普通の関数に対してinlineアノテーションを付けてコンパイルすると次のようなメッセージが表示されました。

WARNING: /Users/taro/Sample.kt: (5, 1) Expected performance impact of inlining 'inline internal fun hoge(): Unit defined in root package' can be insignificant. Inlining works best for functions with lambda parameters

普通の関数をインライン関数にしても効果が薄いよってことらしいです。

*1:正確にはこのforEachはIterableの拡張関数として定義されています。