2010-11-25 9 views
0

データ値を格納し、最後に 'x'データ値を定期的に取得する必要のあるプログラムがあります。C#のスタック上のPeekRange?

最初はスタックがあると思っていましたが、最後の 'x'個の値をピークできるPeekRangeメソッドのようなものがあります。現時点で

私はちょうどリストを使用して、最後を取得し、このような20個の値、と言っている:

var last20 = myList.Skip(myList.Count - 20).ToList(); 

リストは、プログラムが実行されるすべての時間を成長するが、私は今まで、最後にしたいです20値。誰かがより良いデータ構造について助言を与えることができますか?

答えて

1

あなたがスタックに言及して以来、私はリストの最後に変更が必要だと思いますか?

この場合、リストは実際には素晴らしい解決策です(キャッシュは効率的で、最後に挿入/削除が速くなります)。しかし、最後のいくつかの項目を抽出するあなたの方法は、IEnumerable<T>がリストによって提供されるランダムアクセスを公開しないので、やや非効率です。したがって、Skip() -Implementationは、最後に到達するまでList全体をスキャンする必要があります(またはコンテナがIList<T>を実装していることを検出するために実行時の型チェックを最初に行います)。インデックスで項目に直接アクセスするか、または2番目の配列が必要な場合はList<T>.CopyTo()を使用する方が効率的です。

最初に高速取り外し/挿入が必要な場合は、リングバッファまたは(二重)リンクリスト(LinkedList<T>を参照)を検討するとよいでしょう。リンクされたリストのキャッシュ効率は低下しますが、双方向からナビゲートして変更するのは簡単で効率的です。リングバッファは実装するのが少し難しくなりますが、キャッシュとスペースの効率が向上します。小さな値の型や参照型だけが格納されている方が良いでしょう。特に、バッファサイズが固定されている場合。

4

おそらくring bufferを使用しています。あなた自身で実装するのは難しいことではありませんが、AFAIKではフレームワークによって実装が提供されていません。

1

(リストが20を超える場合)、あなただけのremoveat(0)それぞれの後に追加することができ、そのリストは長く20よりなることはありませんアイテム。

1

あなたはスタックを言いましたが、あなたは最後の20個のアイテムしか望んでいないと言っています。私はこれらの2つの要件が本当に一緒に行くとは思わない。

私は、ヨハネスがリングバッファーについて正しいと言います。 .NETでこれを実装するのは非常に簡単です。 Queue<T>を使用し、容量(20)に達するとすべてのエンキュー(プッシュ)でデキュー(ポップ)を開始します。

あなたのPeekRangeは、最近の最低に最新のものから列挙したい場合は、あなたがreturn _queue.Reverse().GetEnumerator();

ようsomehingを行うには GetEnumeratorを定義することができます