2016-12-24 12 views
3

F#でネストされた関数のパフォーマンスに問題はありますか?入れ子関数のパフォーマンス(F#)

配列内のすべての項目に対して呼び出される関数があり、この関数にネストされた内部関数がある場合は、すべての繰り返しで宣言し、内部のネストされた関数をすべて割り当てる必要がありますか?

非常に非効率だと思われますが、プライベートな外部関数とは対照的に入れ子関数の読みやすさが本当に好きです。

+3

おそらくベンチマークで、 –

+1

を参照してください。[F#interactive #time](https://docs.microsoft.com/en-us/dotnet/articles/fsharp/tutorials/fsharp-interactive/) - [例] (https://github.com/jack-pappas/fsharp-logic-examples/blob/d78b170ecfd7526971153e2f2a27446e0c51dd6e/Examples/dp.fsx#L41) –

答えて

13

ネストされた関数は、FSharpFuncを継承するクラスにコンパイラによって抽出されます。モジュール内でネストされているか、親関数が定義されている型にコンパイルされます。コンパイラは基本的に、機能。

実行時に発生することはすべて、これらのオブジェクトのインスタンス化です。インラインコードを実行するのに比べてコストがかかりますが、あなたの精神モデルで予想していたよりも大幅に少ないと思います。

GCに余分なオブジェクトが残っています。このオブジェクトのインスタンシエーションはタイトなループで問題になるでしょうか?単純な実装では、各反復で関数オブジェクトが新たにインスタンス化されます。おそらくはそうです。しかし、F#コンパイラはそれよりもスマートで、一般的にループの本体で使用されている関数をループ外で一度インスタンス化します。だから、コストはおそらくそれほど低いかもしれません。

重大な疑いがある場合は、ILSpyとベンチマークを参照してください。経験則として、それ以上のことを心配せず、入れ子関数を使用してください。

+0

恐ろしい答え。ご協力いただきありがとうございます。 – Connel

+1

クローズアップしていない内部関数については忘れてしまいました。 –

+1

@FyodorSoikin:その点でクロージャと非クロージャの機能に違いはありますか?私はそれを観察していない。 – scrwtp