4

ここで見つけた最も近い質問はC# Dictionary Loop Enhancmentですが、それは役に立ちませんでした。

次のコードは、私のプロジェクトにあるものです。データ構造は非常に複雑なので、説明のために単純な形式で作成しました。

public class BusinessObject
{
    public Dictionary <int, InnerObject> objList = new Dictionary <int, InnerObject>();
    public string Name {set;get;}

    public Dictionary <int, InnerObject> ObjectList // <index, InnerObject>
    {
        get
        {
            return ojbList;
        }
    }
}

...
...
...
// <Name of the BusinessObject, BusinessObject>
public Dictionary <string, BusinessObject> BusinessObjectList; 
// names of all the business objects has an index in this dictionary
public Dictionary <int, string> BusinessObjectListIndexes 

...
...
...

//On receiving the values over TCP, following loop executes. This loop will iterate over about a million values depending on the type of that value:

int currentIndex = 0;
string name = "";
InnerObject tempInnerObject;

for(int i = 0; i < valueCountReceivedOverTCP; i++) // valueCountReceivedOverTCP can be up to 1 million
{
/* 1. */ name = BusinessObjectListIndexes[i];                                     
/* 2. */ tempInnerObject = BusinessObjectList[name].ObjectList[i];                
/* 3. */ tempInnerObject.ReceivedTime = valuesReceivedOverTCP->Time;               

    switch(valuesReceivedOverTCP->Type)
    {
        case TCPType.INT:
            bytearray[0] = valuesReceivedOverTCP->Values[++currentIndex];
                        bytearray[1] = valuesReceivedOverTCP->Values[++currentIndex];
                        bytearray[2] = valuesReceivedOverTCP->Values[++currentIndex];
                        bytearray[3] = valuesReceivedOverTCP->Values[++currentIndex];

                        tempint = BitConverter.ToInt32(bytearray, 0);
 /* 4. */           tempInnerObject.Value = tempint;                      
        break;

        case TCPType.DOUBLE:                                                
                        bytearray[0] = valuesReceivedOverTCP->Values[currentIndex+1];
                        bytearray[1] = valuesReceivedOverTCP->Values[currentIndex+2];

                        bytearray[2] = valuesReceivedOverTCP->Values[currentIndex+3];
                        bytearray[3] = valuesReceivedOverTCP->Values[currentIndex+4];

                        bytearray[4] = valuesReceivedOverTCP->Values[currentIndex+5];
                        bytearray[5] = valuesReceivedOverTCP->Values[currentIndex+6];

                        bytearray[6] = valuesReceivedOverTCP->Values[currentIndex+7];
                        bytearray[7] = valuesReceivedOverTCP->Values[currentIndex+8];

                        currentIndex += 8;                        
                        tempdouble = BitConverter.ToDouble(bytearray, 0);
/* 5. */                tempInnerObject.Value = tempdouble; 


        break;
    }

}

1 から 5 までの行が問題のある行です。ANTS Performance Profiler を使用すると、上記の行に時間がかかっていることがわかりました。それらはすべてかなりの時間がかかります。ライン 2 が主な時間の浪費です。for ループは、約 700,000 の値に対して約 250 ミリ秒かかります。ミリ秒単位ですが、ソフトウェアでは受け入れられないため、削減したいと思います。また、この for ループを 4 つの並列ループに分割しようとしましSystem.Threading.Tasks.Parallel.Invoke()たが、成功しませんでした。

私の質問は、このロジックまたはコードに明らかに問題があると思いますか? このコードをより高速に実行するための解決策は何ですか。.NET ディクショナリのパフォーマンス制限に達した場合は、全体を別の方法で実装する必要があることを理解しています。このコードをより高速に実行するために設計/実装を変更することを意味する場合でも、私はどんな提案も受け付けています。

編集: 最初の TCP メッセージとして、これらの値の順序と合計数を取得します。注文をキーとして保存し、ビジネス オブジェクト名を値として保存しますBusinessObjectListIndexes。最初のメッセージ以降、BusinessObject の名前がわかりません。最初のメッセージで指定された順序で値のみが受信されます。次に、すべてのメッセージで受信した値で BusinessObjectList を更新します。これは、パフォーマンスを改善する必要がある場所です。更新された値を提供する TCP メッセージが 250 ミリ秒ごとに受信されます。

4

1 に答える 1

0

BusinessObjectListIndexesプロパティとプロパティの両方でキーのみをObjectListインデックスとして使用しているようです。ただし、Dictionaryクラスはこれを認識していないため、キー/インデックスを検索する必要があります。

Arrayサイズが事前にわかっている場合は に変更し、サイズList<int>がわからない場合や単に使いやすい場合は に変更すると、パフォーマンスが向上するのではないかと思います。(平均?)サイズによっては、別のタイプの方が適している場合がありますが、ここでは辞書が正しい選択ではないようです。

于 2013-01-24T21:10:37.007 に答える