我在這裏可以找到的最接近的問題是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號線是主要的時間浪費。對於大約700,000個值,for循環大約需要250毫秒。即使它只有幾毫秒,我想減少它,因爲這對於軟件來說是不可接受的。我也嘗試使用System.Threading.Tasks.Parallel.Invoke()
將此循環分成4個並行循環,但沒有成功。
我的問題是 - 你看到這個邏輯或代碼有什麼明顯的錯誤嗎?什麼是解決這個代碼運行得更快的解決方案。我明白,如果我已經達到.NET Dictionary的性能限制,那麼我必須以不同的方式實現整個事情。我打開任何建議,即使這意味着改變我的設計/實現以使代碼更快運行。
編輯: 作爲第一個TCP消息,我得到這些值的順序和總數。我將訂單另存爲BusinessObjectListIndexes
中的一個關鍵字和業務對象名稱。第一條消息向前我沒有得到BusinessObject名稱。只有值按照第一條消息指定的順序接收。然後,我用每條消息中收到的值更新BusinessObjectList。這是我需要改進性能的地方。每250毫秒接收一次TCP消息,提供更新的值。
如果內存不是那麼重要,你可以嘗試用更大的容量初始化字典,看看是否有一個點可以減少時間http://www.dotnetperls.com/dictionary-optimization – keyboardP
我'對於那裏的邏輯有點困惑......你可以重新組織那些東西,並使用Dictionary而不是你現在擁有的2個字典嗎?然後你的第1行和第2行會合併成tempInnerObject = BusinessObjectList [i] .ObjectList [i]; ...也許還有一個邏輯問題,我被用來索引2個東西,但這也可能是複製粘貼+編輯工件 –
@Mike Trusov,我無法將這2個字典合併成一個單詞,因爲 - 數據通過TCP接收是基於索引。所以我需要上面提到的for循環中的業務對象的索引。因此,字典用於將業務對象名稱轉換爲索引。在所有其他時間,業務對象字典都是通過使用其名稱來訪問的。 –
silverspoon