2016-12-01 41 views
4

私はC#console-appを作成しています。いくつかのクリティカルなパスがあり、構造体の作成には構造体のガベージコレクションが不要なので、クラスを作成するよりも高速であると考えました。しかし私のテストでは、私はその反対を見つけた。構造体がクラスより遅いのはなぜですか?

以下のテストでは、1000個の構造体と1000個のクラスを作成します。

class Program 
{ 
    static void Main(string[] args) 
    { 
     int iterations = 1000; 
     Stopwatch sw = new Stopwatch(); 

     sw.Start(); 
     List<Struct22> structures = new List<Struct22>(); 
     for (int i = 0; i < iterations; ++i) 
     { 
      structures.Add(new Struct22()); 
     } 
     sw.Stop(); 
     Console.WriteLine($"Struct creation consumed {sw.ElapsedTicks} ticks"); 

     Stopwatch sw2 = new Stopwatch(); 
     sw2.Start(); 
     List<Class33> classes = new List<Class33>(); 
     for (int i = 0; i < iterations; ++i) 
     { 
      classes.Add(new Class33()); 
     } 
     sw2.Stop(); 
     Console.WriteLine($"Class creation consumed {sw2.ElapsedTicks} ticks"); 


     Console.ReadLine(); 
    } 
} 

マイクラッセ/構造体は単純です:

class Class33 
{ 
    public int Property { get; set; } 
    public int Field; 
    public void Method() { } 
} 

struct Struct22 
{ 
    public int Property { get; set; } 
    public int Field; 
    public void Method() { } 
} 

結果(ドラムロールしてください...)

Struct creating consuming 3038 ticks 
Class creating consuming 404 ticks 

そこで質問です:なぜそれは10倍近くかかるだろうクラスの時間はStructの時間よりも短くなりますか?

EDIT。私は、プロパティに整数を割り当てるだけで、このプログラムを「何かする」ようにしました。

static void Main(string[] args) 
    { 
     int iterations = 10000000; 
     Stopwatch sw = new Stopwatch(); 

     sw.Start(); 
     List<Struct22> structures = new List<Struct22>(); 
     for (int i = 0; i < iterations; ++i) 
     { 
      Struct22 s = new Struct22() 
      { 
       Property = 2, 
       Field = 3 
      }; 
      structures.Add(s); 
     } 
     sw.Stop(); 
     Console.WriteLine($"Struct creating consuming {sw.ElapsedTicks} ticks"); 

     Stopwatch sw2 = new Stopwatch(); 
     sw2.Start(); 
     List<Class33> classes = new List<Class33>(); 
     for (int i = 0; i < iterations; ++i) 
     { 
      Class33 c = new Class33() 
      { 
       Property = 2, 
       Field = 3 
      }; 
      classes.Add(c); 
     } 
     sw2.Stop(); 
     Console.WriteLine($"Class creating consuming {sw2.ElapsedTicks} ticks"); 


     Console.ReadLine(); 
    } 

となり、結果は私にとって驚異的です。クラスはまだ少なくとも2倍ですが、整数を割り当てるという単純な事実には20倍のインパクトがあります!

Struct creating consuming 903456 ticks 
Class creating consuming 4345929 ticks 

EDIT:私のクラスまたは構造体には参照型が存在しないので、私はメソッドへの参照を削除:

class Class33 
{ 
    public int Property { get; set; } 
    public int Field; 
} 

struct Struct22 
{ 
    public int Property { get; set; } 
    public int Field; 
} 
+4

あなたは実際に意味のあることはしていません。何もしない測定は実際にあなたに何も言わない。 – Servy

+0

ストラクチャとクラスは長い間議論されています。問題を見つけるためには本当に重要な道筋である部品を測定する必要があります。 [このディスカッション](http://stackoverflow.com/questions/3942721/structs-versus-classes) –

+5

[これら](https://msdn.microsoft.com/en-us/library/ms229017.aspx)構造体やクラスの使用について考えるときに考慮すべき事柄:_ "型のインスタンスが** small **であり、通常は**短命**であるか、または他のオブジェクトに一般に埋め込まれている場合、クラスの代わりにstructを使用します。 X型は、型に以下の特性がすべて含まれていない限り構造体を定義します。 これは基本的な型(int、doubleなど)に似た**単一値**を論理的に表します 16バイト。 **不変**。 頻繁に囲む必要はありません。 "_ –

答えて

0

としては、クラスには多くの考慮事項を持って対構造体を決める、コメントしました。私は多くの人がインスタンス化に関心を持っているのを見ていません。これは、通常、この決定に基づくパフォーマンスの影響のごく一部です。

私はあなたのコードでいくつかのテストを実行し、インスタンスの数が増えると構造体が高速になることが興味深いことがわかりました。

あなたの主張が真実ではないと思われるので、私はあなたの質問に答えられません。クラスは必ずしもStructsよりも速くインスタンス化するとは限りません。私が読んだものはすべてその反対ですが、あなたのテストは興味深い結果をもたらします。

あなたが実際に掘り下げて、なぜ結果を得るのかを調べるために使用できるツールがあります。

10000 
Struct creation consumed 2333 ticks 
Class creation consumed 1616 ticks 

100000 
Struct creation consumed 5672 ticks 
Class creation consumed 8459 ticks 

1000000 
Struct creation consumed 73462 ticks 
Class creation consumed 221704 ticks 
+0

こんにちは。同意する。私は記憶がなくなり、クラスがまだまだ高速であることが分かりました。私のテストが代表でない場合はお詫び申し上げます。通常、人々はこのフォーラムで質問します。回答は通常、「TRY IT」です。だから私はやった。私のテストが「代表」でない場合は、再度お詫び申し上げます。私は今なぜ私のテストを修正するのかを理解しています。 –

1

性能の差は、おそらく(または少なくとも部分的に)簡単な例で説明できます。 structures.Add(new Struct22());については

これは本当に何が起こるかです:

  • Struct22が作成され、intializedされます。
  • Addメソッドが呼び出されましたが、値タイプであるため、コピーが返されます。したがって、この場合のAddを呼び出す

オーバーヘッド、新しいStruct22を作成し、元からそこにすべてのフィールドとプロパティをコピーすることによって被りました。

private static void StructDemo() 
{ 
    List<Struct22> list = new List<Struct22>(); 

    Struct22 s1 = new Struct22() { Property = 2, Field = 3 }; // #1 
    list.Add(s1);       // This creates copy #2 
    Struct22 s3 = list[0];     // This creates copy #3 

    // Change properties: 
    s1.Property = 777; 
    // list[0].Property = 888; <-- Compile error, NOT possible 
    s3.Property = 999; 

    Console.WriteLine("s1.Property = " + s1.Property); 
    Console.WriteLine("list[0].Property = " + list[0].Property); 
    Console.WriteLine("s3.Property = " + s3.Property); 
} 

これはAdd()list[0]の使用の両方がコピーが作られる原因となったことを証明し、出力されます:スピードではなく、コピーが行われているという事実に焦点を当てていない、実証するために


s1.Property = 777
リスト[0] .Property = 2
s3.Property = 999

これは、構造体の動作がオブジェクトに比べて大幅に異なる可能性があり、使用するものを決定する際のパフォーマンスは単なる1つの側面であることを覚えておいてください。

関連する問題