2016-07-16 6 views
1

この機能を考える:私は別の番号のデータ型を送信する場合メソッドにパラメータとして異なる数値型を送信するとパフォーマンス上の問題がありますか?

void function(Double X, Double y, Double Z); 

がパフォーマンス上の問題はありますか?例:

function(1, 2, 3); //int, int, int 
function(1, 2.2, 1); //int, double, int 
function(1.3f, 3.4, 2.34f) //single, double, single 
function(1.2f, 1, 1) //single, int, int 

.NET JITはこれをどのように管理しますか?それはボクシングのアンボクシングですか?これはパフォーマンスに影響しますか?

+1

実際のリテラルまたは変数について話していますか?それらがリテラルの場合、C#コンパイラは暗黙の変換を実行しており、実行時コストはありません。それ以外の場合、実行時変換にはわずかなコストがかかりますが、割り当てはありません(ボクシング/アンボクシング)。 –

+1

コンパイル時に既知の型に定数がキャストされています。おもちゃコンパイラーを書くすべての学部は、コンパイラーでそれをすべて行います。私は.NETコンパイラの人は管理できるかもしれないと思う。つまり、あなたの例のコードがあなたが求めているコードであると仮定します。 –

+1

パラメータの変換時間がメソッドの実行に要する合計時間と比較して重要な場合は、タイトなループでこのメソッドを呼び出すと、パフォーマンスコストが問題になります。 – MickyD

答えて

4

正確な例はコンパイラによって変換されるため、パフォーマンス上のペナルティはありません。この例を少し変更すると:

static void Test(double x, double y, double z) 
{ 
    Console.WriteLine(x * y * z); 
} 

static void Main() 
{ 
    double d1 = 1; 
    double d2 = 2; 
    double d3 = 3; 
    float f1 = 1; 
    float f2 = 2; 
    float f3 = 3; 
    int i1 = 1; 
    int i2 = 2; 
    int i3 = 3; 

    Test(i1, i2, i3); 
    Test(i1, d2, i3); 
    Test(f1, d2, f3); 
    Test(f1, i2, i3); 
} 

次にストーリーが異なります。それは変換コードを放出することが必要ですのでcompilierは、例えば、あなたが見ることができますTest

IL_004b: ldloc.s V_6 // Load the variable i1 onto the stack 
IL_004d: conv.r8   // Convert it to a double 
IL_004e: ldloc.1   // Load the variable d2 onto the stack 
IL_004f: ldloc.s V_8 // Load the variable i3 onto the stack 
IL_0051: conv.r8   // Convert it to a double 
// And call the function: 
IL_0052: call  void Example.ExampleClass::Test(float64, 
                float64, 
                float64) 

への2回目の呼び出しのためのコードを見てみましょう、私たちのための変換を行う可能性は低いだろうそれは2つの非2倍のそれぞれについてもう1つの命令を出さなければならない。これは自由行動ではなく、計算に時間がかかります。

これらのことはすべて、非常にタイトなループでこの関数を呼び出さない限り、この問題を想像するのは難しいでしょう。

編集

また、プロパティアクセサに目を光らせておいてください。たとえば、デモオブジェクトがforループ中に長さを変更しない場合、これらの2つのメソッドは論理的に同じですが、最初の呼び出しではdemo.Lengthが複数回呼び出されます。これは一度呼び出すよりも遅くなります。

var demo = CreateDemo(); 
for (int i = 0; i < demo.Length; ++i) 
{ 
    // ... 
} 

// .. vs .. 

var demo = CreateDemo(); 
int len = demo.Length; 
for (int i = 0; i < len; ++i) 
{ 
    // ... 
} 
+0

ILの説明は非常に有益でした。はい、私はOpenGLのゲームループでこれを実行しようとしていますが、変数が常に同じタイプではないことに気付きました。いくつかはfloat、some double、intです。それが私が尋ねた理由です。 2つの異なるコンピュータ、つまり現代(2013)と非常に古い(2001)の2種類の方法で2つの方法でプログラムをテストしました。私の最初の解決策であるテンプレートを使用すると、古いものは非常に速く数千のGLラインでストレスを受けていました。私は、それがパフォーマンスに及ぼす影響を見るために、ただ1つのデータタイプで調整を試みると思います。 –

+1

十分に公正で、本当に重要なケースがあります。多くの不必要な関数呼び出しのような他の潜在的なパフォーマンスの問題を調べることを覚えておいてください(例えば、単純なアクティビティのためにヘルパー関数があれば、値をスタックにプッシュしてからインラインで同じアクティビティを実行するときの機能はより速くなります)。また、配列アクセスやプロパティアクセスのようなものは、場合によっては避けることができる関数呼び出しです。 –

+0

ああ!プロパティアクセスはO.Oのパフォーマンスに影響しますか? 実際に私は多くのプロパティjajajaにアクセスしている可能性があります。おそらく、これは何かになる可能性があります... –

関連する問題