web-dev-qa-db-ja.com

C#/ F#パフォーマンスの比較

新しいF#言語の適切な使用法を示すために、Webで利用可能なC#/ F#パフォーマンス比較はありますか?

54
Vijesh VP

自然なF#コード(例:関数型/不変)は、自然な(命令型/可変オブジェクト指向)C#コードよりも低速です。ただし、この種のF#は通常のC#コードよりもはるかに短いです。明らかに、トレードオフがあります。

一方、ほとんどの場合、C#コードのパフォーマンスと同等のF#コードのパフォーマンスを実現できます。これには通常、命令型または変更可能なオブジェクト指向のスタイルでコーディングし、ボトルネックをプロファイルして削除する必要があります。 C#で使用するのと同じツールを使用します。 .Netリフレクターとプロファイラー。

とはいえ、パフォーマンスを低下させるF#の生産性の高い構造に注意する必要があります。私の経験では、次のようなケースを見ました。

  • 数十億回実行されたコードでのみ参照(vs.クラスインスタンス変数)

  • F#比較(<=)とSystem.Collections.Generic.Comparerの比較(例:バイナリ検索または並べ替え)

  • 末尾呼び出し-コンパイラまたは.Netランタイムで最適化できない特定の場合のみ。コメントに記載されているように、.Netランタイムに依存します。

  • F#シーケンスはLINQより2倍遅い。これは、seq <_>の変換を実装するための参照とF#ライブラリの関数の使用によるものです。これは、SeqモジュールをLinq、PLinqまたはDryadLinqを使用する同じシグネチャを持つものに置き換える可能性があるため、簡単に修正できます。

  • タプル、F#タプルはヒープ上でソートされたクラスです。場合によっては、構造体を使用するために支払う可能性があるint * intタプル。

  • 割り当て。クロージャは、アクセスされた変数を記憶するnew演算子で作成されたクラスであることを覚えておく価値があります。クロージャを「持ち上げる」か、アクセスされた変数を引数として明示的に受け取る関数に置き換えることは価値があるかもしれません。

  • インラインを使用して、特に一般的なコードのパフォーマンスを改善してみてください。

私の経験は、まずF#でコーディングし、重要な部分のみを最適化することです。場合によっては、F#を微調整するよりも、低速の関数をC#で記述する方が簡単な場合があります。ただし、プログラマーの効率の観点からは、F#で開始/プロトタイプを作成してから、プロファイリング、逆アセンブル、最適化を行うことが理にかなっています。

つまり、プログラム設計の決定により、F#コードはC#よりも遅くなる可能性がありますが、最終的には効率を上げることができます。

53
Stefan Savev
24
Brian R. Bondy

このトピックに関する(または関連する)リンクをいくつか紹介します。

Robert Pickeringのブログ(またはScott Hanselmanでしたか?)の別の投稿から覚えているようですが、結局、両方が同じフレームワークに座っているため、できます両方から同じパフォーマンスを得ることができますが、そのためには言語の自然な表現を「ねじる」必要がある場合があります。私が覚えている例では、彼はC#と同等のパフォーマンスを得るためにF#をひねる必要がありました...

11
Benjol