2011-08-06 16 views
5

は、我々は、以下の方法(擬似C#)を持っていることを想像して返すの通話のためのより良い性能特性(メモリ賢明な)を持つ:配列やイテレータ - 1/2の要素

1は、少ないメモリを消費します
static IEnumerable<T> Iterator<T>() 
{ 
    switch (SomeCondition) 
    { 
     case CaseA: 
      yield return default(T); 
     case CaseB: 
      yield return default(T); 
      yield return default(T); 
     case CaseC: 
      yield return default(T); 
     default: 
      break; 
    } 
} 

static IEnumerable<T> Array<T>() 
{ 
    switch (SomeCondition) 
    { 
     case CaseA: 
      return new[] { default(T) }; 
     case CaseB: 
      return new[] { default(T), default(T) }; 
     case CaseC: 
      return new[] { default(T) }; 
     default: 
      break; 
    } 
} 

このメソッドのように多くの呼び出しがある場合は、GCサイクルが短くなります。このようなEnumerable.Once()シナリオを実装するには、独自のEnumerable/Enumeratorを記述することは理にかなっていますか?

+6

あなたがコンパイルされ、有効に適切な最適化とリリースビルドの両方のサンプルを実行したときに何が起こったのか? –

+5

どちらもボトルネックではありません。最も読みやすいものを選んでください。 –

+0

メソッドはそれらのシグネチャを*正確に*持つ必要がありますか?これは間違いなくボトルネックですか?ユースケースは何ですか?興味深いオプションがいくつかありますが、より多くの情報が必要です。 –

答えて

1

この1つは他のものの両方よりも高速です:

static T[] Array<T>() 
{ 
    switch (SomeCondition) 
    { 
     case CaseA: 
      return new[1]; 
     case CaseB: 
      return new[2]; 
     case CaseC: 
      return new[1]; 
     default: 
      break; 
    } 
} 

しかし、本当に多くの問題ではするつもりはありません。

0

配列は少ないメモリとのサイクルを取るが、あなたは返されたデータに基づいて行動したい場合は、イテレータは、最終的に物事をスピードアップするでしょうアルゴリズムの最良の実装としてイテレータと一緒に行きたいと思うだろう。

1

それは例えば、イテレータとのより良いだろう、T. A大型構造体、文字列、またはバイト配列に依存します。しかし、一般的に、1つまたは2つのアイテムの場合、配列はおそらく小さくなります。

しかし、それはポイントを逃します。それが速いのは、問題のスペースがパフォーマンスに重要でないほど小さいためです.1つまたは2つのアイテムシーケンスがアプリのパフォーマンスの原動力になる可能性は低いです。そのシナリオでは、パフォーマンスではなく、明快さ、保守性、そして良い習慣のような他の要因について私はずっと心配していました。このうち

、あなたはまだ発生していないプログラマはイテレータはまだ簡単にそれを理解することができるので、配列は、明確またはクリーンであることを主張することができます。個人的に、私はイテレータは、より優れた性能特性を有する傾向があるので、配列の前にイテレータに手を伸ばすのが習慣になりたいので、私は、歩留まりのイテレータを好む、と私は他の人でも同じ習慣を奨励したいです。

+0

+1 - 「わかりやすく保守性があり、良い習慣をつくるなど、他の要素がはるかに心配です」と完全に同意してください! –

+0

あなたのクレームをバックアップするためのパフォーマンス番号がありますか? AFAICSのため、配列またはイテレータのコピー数は等しくなります(配列は一度にすべてを支払うため、各イテレータは返されるたびに断片的になります)。要素の数が自明でない場合は、より多くのメモリを使用するため、配列のパフォーマンスが低下する可能性がありますが、配列を反復することはほとんどの場合、列挙型を反復するよりも高速です。 'yield return'は、コルーチン状態を追跡するために、それ自身のオーバヘッドがあります。 –