ここで見つけた最も近い質問は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 ミリ秒ごとに受信されます。