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 号线是主要的浪费时间。对于大约 700,000 个值,for 循环大约需要 250 毫秒。即使它以毫秒为单位,我也想减少它,因为这对于软件来说是不可接受的。我也尝试过将此 for 循环拆分为 4 个并行循环,System.Threading.Tasks.Parallel.Invoke()但没有成功。

我的问题是——你看到这个逻辑或代码有什么明显的错误吗?有什么办法可以让这段代码运行得更快。我知道如果我达到了 .NET Dictionary 的性能限制,那么我必须以不同的方式实现整个事情。即使这意味着更改我的设计/实现以使此代码运行得更快,我也愿意提出任何建议。

编辑: 作为第一个 TCP 消息,我得到了这些值的顺序和总数。我将订单保存为键,并将业务对象名称保存为BusinessObjectListIndexes. 从第一条消息开始,我没有得到 BusinessObject 名称。仅以与第一条消息指定的顺序相同的顺序接收值。然后,我使用在每条消息中收到的值更新 BusinessObjectList。这是我需要改进性能的地方。每 250 毫秒收到一条 TCP 消息,提供更新的值。

4

1 回答 1

0

您似乎只使用BusinessObjectListIndexesObjectList属性中的键作为索引。该类Dictionary虽然不知道这一点,但仍然必须搜索您的键/索引。

如果您将它们更改为Array,如果您事先知道尺寸,甚至是List<int>,如果您不知道尺寸或只是觉得它更易于使用,我怀疑您会获得更好的性能。根据(平均?)大小,您可能会发现另一种更适合的类型,但关键是字典在这里似乎不是正确的选择。

于 2013-01-24T21:10:37.007 回答