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; }
    ...
    ...
    ...
}

我到处使用字典的原因是因为我需要通过键访问列表。

我在一个for循环中有以下几行,它运行了超过 550,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 次)。这对我的申请是不可接受的。它必须在 50 毫秒内完成上述行之一。谁能建议如何优化上述操作的性能?我愿意接受任何建议,即使这意味着在必要时重新定义相关类。

4

2 回答 2

3

你的时间太慢了。对于这类问题,一毫秒是永恒的,字典中的 550,000 个元素是鸡饲料。我的第一个想法是您的问题在于您的数据源,而不是您的字典;在网络通信中,一毫秒的时间要多得多。

如果字典问题,看看你的记忆。字典是哈希表,本质上是数组。当你创建一个时,它从一个特定大小的数组开始。随着它的扩展,它会分配一个新的、更大的数组并丢弃旧的数组。如果您的 550,000 元素字典开始时有 10 个元素的空间,它将使“可用”内存充满无法使用的大块内存,因为下一次分配仍然更大。GC 将努力重新排列内存并使所有这些块连续,如果它在您运行两个问题语句时这样做,它会减慢速度。要解决此问题,请在创建字典时首先为 550,000 个条目分配空间。这可能就足够了,但也调用GC.Collect(). 这将一次性完成 GC 工作,并在您需要时为您提供干净的时间安排。

另一个内存问题可能是myDebugValues。对于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 回答