4

そのような機能は存在しますか?サーバーモードで実行されているJavaHotSpotのようなものですが、.Netアプリケーション用です。

編集: もう少し情報。私は小さなアプリケーション(F#で書かれています)を持っていて、その中にたくさんの小さな関数があります。このように:

let printable b =
    if b >= ' 'B && b <= '~'B
    then b else '.'B

パフォーマンスが悪いことに気づきました。プロファイリングを行った後、そのような関数はすべて何百万回も呼び出されていることがわかりました。私はそれらを作成しinline、パフォーマンスを向上させました(5倍以上、それ以上かもしれません)。

良いね。パフォーマンスは今は良いです。しかし、なぜフレームワークはそれをしなかったのですか?それは私のコードと関数が呼び出された頻度についての十分な情報を持っています。1M回呼び出された関数をインライン化しないのはなぜですか?

EDIT2: インライン関数の違いを測定するためのサンプルテスト:

    open System

    let printableByte b =
        if b >= ' 'B && b <= '~'B
        then b else '.'B

    let foo (arr : byte[]) = 
        for i in 0..arr.Length-1 do
            arr.[i] <- printableByte (arr.[i])
        arr.Length / 1000

    let main() =
        let sum = ref 0
        let arr = Array.create 1000000 0uy

        let stopWatch = System.Diagnostics.Stopwatch()
        stopWatch.Start()
        for x in 0..5000 do
            sum := !sum + (foo arr)

        stopWatch.Stop()
        printfn "%d" !sum 
        printfn "total time = %A" stopWatch.ElapsedMilliseconds
        ()

    main()

インライン化されていない場合は19.5秒、printableByteインライン化されている場合は13.6秒実行されます。

EDIT3: この時間差は、x86ターゲット用にコンパイルされ、x64ホストで実行されている場合にのみ表示できます。「anycpu」またはx64用にコンパイルされた場合、時間差はありません。

したがって、「小さな関数」と最適化に問題はありません。

4

3 に答える 3

4

はい、このブログが示すように、CLRは実行時の最適化を行います。この投稿によると、仮想メソッドはインライン化されていないことに注意してください。

これらの方法はどちらもインライン化されていません。

  • 再帰的方法
  • 仮想メソッド(レシーバー変数の静的タイプが封印されている場合でも)

コードで関数はどのようにprintable呼び出されますか?F#コンパイラがそれをクロージャでラップすると、最初は予期していなかった場合でも、多くの場合、「仮想メソッド」のケースに分類されます。

于 2012-05-04T19:13:59.163 に答える
1

FSIでこのコードをテストすることは、プロジェクトをモードでコンパイルすることと同じではないことに注意してください。Release

私の非常に非科学的なテストは、あなたが与えたパフォーマンステストがに追加されたDebug場合にうまく実行されることを示しています。inlineprintableByte

ただし、がモードでinline追加された場合Release、プログラムは実際にはそれがない場合よりもパフォーマンスが低下します。F#コンパイラチームまたはいくつかの逆アセンブルが、その理由を教えてくれると確信しています...

F#を使用した私の経験では、インライン最適化を手動で適用する必要はほとんどありません。必ずコンパイルしてReleaseください!

編集:ああ、はい!特別な理由がない限り、必ず「任意のCPU」モードでコンパイルしてください(通常、私の理由はF#のx86 COMライブラリと相互運用する必要があることです)。

于 2012-05-04T21:20:20.853 に答える
0

はい、.net Frameworkは、それが実行されているプラ​​ットフォームのコードを最適化します。それは多くの要因を考慮に入れています。ただし、実行されないことがいくつかあります。たとえば、SIMD命令が利用可能な場合、それらを使用するとは思われません。しかし、それは一般的に最適化の良い仕事をします。

于 2012-05-04T18:24:38.003 に答える