Kotlin日本語和訳より、inline関数lock()は
lock(l) { foo() }
コンパイル後
l.lock() try { foo() } finally { l.unlock() }
のようにコンパイラに処理されるようです。
こうすることにより、実行時間を短くしているのは分かったのですが、
コンパイル後で、何が実行時間を短くしたか分かりません。
確かに、コードがインライン化され展開されていますが、関数の呼び出しコストが下がっているように思えません。
何が、実行コストを下げているを教えてください。お願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
こちらの和訳から引用して説明します。
高階関数を使用すると、特定のランタイムペナルティを課せられます。各関数はオブジェクトであり、それはクロージャ、すなわち、関数の本体でアクセスされるそれらの変数をキャプチャします。メモリ割り当て(関数オブジェクトとクラス用の両方)と仮想呼び出しは、実行時のオーバーヘッドを招きます。
しかし、多くの場合、オーバーヘッドのこの種のラムダ式をインライン化することによって解消することができると思われます。
ということで、インライン化によって解消できるのはラムダ生成のコストであって、関数呼び出しのコストではありません。
投稿2017/05/28 22:18
総合スコア145121
0
ベストアンサー
理由の一つには「ローカル変数のアクセス効率化」があるのではないかと思い、byte codeを調べてみました。
次のようなコードを考えてみます。
kotlin
1... 2void foo(l: Lock) { 3 val a = ...; 4 lock(l) { 5 a += 1 6 foo(a) 7 } 8}
インライン展開されない場合、{ a += 1; foo(a) }
の部分はラムダ式(?)となるだろうと思います。実装の話になりますが、ラムダ式はjavaで表現するとおおよそ次のようなものになるようです。
java
1import kotlin.jvm.internal.Ref.IntRef; 2import kotlin.jvm.functions.Function0; 3 4void foo(Lock l) { 5 IntRef _a = new IntRef(...); 6 lock(l, new $1(_a)); 7 8 // lambdaを表現する内部的なクラス 9 class $1 implements Function0 { 10 $1(IntRef _a) { 11 $a = _a; 12 } 13 14 Void invoke() { 15 $a.element += 1; 16 foo($a.element); 17 } 18 } 19}
javaと異なりKotlinではlambda内からアクセスすることのできるローカル変数はmutableでかまいません。ご存知のようにjavaのlambda/内部クラスでは外側のスコープにあるローカル変数はimmutableでなければならないという制限があります。(この点でもkotlinはbetter javaたらんとしています...っていうかC#やScalaでもできるのでKotlinができない訳にはいかないのかも知れません)
ただJVMはあるメソッドのスタックフレーム上にあるローカル変数をそのメソッド以外からアクセスするbyte codeをサポートしていないので、上記のように実装が幾分トリッキーなことになっています。
つまりインライン関数にしておかないと、ラムダ式から外側のローカル変数を更新するようなコードを実現するために、ローカル変数の内部実装がintではなくIntRefになり、lambdaのクロージャーの生成(new $1)に内部でアクセスするローカル変数を引き渡したりする余分なコードが増えてしまいます。
インライン関数にしておきさえすればこのようなオーバーヘッドを削減できますね。
以上がインライン化する目的の一つになっているように思います。
投稿2017/05/28 22:27
総合スコア18392
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/28 22:37 編集
2017/05/28 22:43
退会済みユーザー
2017/05/29 06:56
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/05/29 06:58