2

次のコードがあります。

// Dictionary which I want to optimize
Dictionary<string, MyClass> myDict;
//
Dictionary<int, KKSKey> kksKeyList;

...    
...
...

// Classes
[Serializable]
public class MyClass : MyBaseClass
{
    Dictionary<int, DebugValue> myDebugValues;    
    ...
    ...
    ...
}

//
[Serializable]
public class DebugValue
{
    public int ValueType {get;set;}
    public double Value {get;set;}
    ...
    ...
    ...
}

public class KKSKey
{
    public string KKS { set; get; }
    public string Variable { set; get; }
    ...
    ...
    ...
}

私がどこでも辞書を使用した理由は、キーでリストにアクセスする必要があるからです。

for550,000 回 (はい!) をわずかに超えるループに次の行があります。myDictには約 10,000 個のアイテムkksKeyListがあり、550,000 個以上のアイテムがあります。

次の各行が に対して実行されi = 0 to 550,000ます。

myDict[kksKeyList[i].KKS].myDebugValues[i].ValueType = DOUBLE;
myDict[kksKeyList[i].KKS].myDebugValues[i].Value = tempdouble;

基本的に、上記の行は、TCP 経由で受信した生データでディクショナリ項目を埋めています。上記の各行は、forループごとに約 90 ~ 100 ミリ秒かかります (550,000 回)。これは私のアプリケーションでは受け入れられません。上記の行の 1 つを 50 ミリ秒以内に完了する必要があります。上記の操作のパフォーマンスを最適化する方法を誰かが提案できますか? 必要に応じて関連するクラスを再定義することを意味する場合でも、私はどんな提案にもオープンです。

4

2 に答える 2

3

あなたのタイミングは遅すぎます。この種の問題ではミリ秒は永遠であり、辞書の 550,000 要素は鶏の餌です。私が最初に考えたのは、問題は辞書ではなく、データ ソースにあるということです。1 ミリ秒は、ネットワーク通信でははるかに長い時間です。

辞書に問題がある場合は記憶力を調べてください。辞書は、基本的には配列であるハッシュ テーブルです。作成すると、特定のサイズの配列から始まります。拡張すると、新しいより大きな配列が割り当てられ、古い配列は破棄されます。550,000 要素のディクショナリが 10 要素用のスペースで始まる場合、次の割り当てがさらに大きくなるため、使用できないメモリの大きなチャンクが散らばった「使用可能な」メモリが残ります。GC はメモリを再配置し、これらすべてのブロックを連続させようと懸命に働きます。2 つの問題ステートメントを実行しているときにこれを行うと、速度が低下します。これを修正するには、ディクショナリを作成するときに、最初に 550,000 エントリのスペースを割り当てます。おそらくそれで十分ですが、GC.Collect(). これにより、GC の作業が一気に完了し、必要なタイミングでクリーンなタイミングが得られます。

別のメモリの問題が考えられますmyDebugValues。の 550,000 エントリごとに、これらの 1 つがありますmyDict。最初から myDict を大きくしたかったように、これらも小さくする必要があります。ListDictionary または HybridDictionary ( System.Collections.Specialized ) を提案することさえあるかもしれません。

メモリの重要な点は、仮想メモリではなく実メモリのみを使用することです。マシンがページングを開始すると、問題が発生します。そして、あなたの GC を満足させてください。

これが役立つことを願っています。そうでなければ、他の誰かがより良い答えを思いつくことを願っています. (私は Urik のものを気に入りましたが、オプティマイザはおそらく既にそれを行っています。)

于 2012-06-22T18:59:55.130 に答える
2

あなたが試すことができます:

string kks = kksKeyList[i].KKS;
myDict[kks].myDebugValues[i].ValueType = DOUBLE;
myDict[kks].myDebugValues[i].Value = tempdouble;

または多分:

myDict[kksKeyList[i].KKS] = new DebugValue(DOUBLE, tempdouble)

それがあなたのコンストラクタに合っているなら...

于 2012-06-21T07:58:04.550 に答える