Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
帮助C#.NET通用集合的性能和优化_C#_.net_Performance_Generics_Dictionary - Fatal编程技术网

帮助C#.NET通用集合的性能和优化

帮助C#.NET通用集合的性能和优化,c#,.net,performance,generics,dictionary,C#,.net,Performance,Generics,Dictionary,我试图优化一段.NET 2.0 C#代码,如下所示: Dictionary<myType, string> myDictionary = new Dictionary<myType, string>(); // some other stuff // inside a loop check if key is there and if not add element if(!myDictionary.ContainsKey(currentKey)) { myDict

我试图优化一段.NET 2.0 C#代码,如下所示:

Dictionary<myType, string> myDictionary = new Dictionary<myType, string>();
// some other stuff
// inside a loop check if key is there and if not add element
if(!myDictionary.ContainsKey(currentKey))
{
   myDictionary.Add(currentKey, "");
}
Dictionary myDictionary=newdictionary();
//一些其他的东西
//在循环内部,检查键是否存在,如果不存在,则添加元素
如果(!myDictionary.ContainsKey(currentKey))
{
myDictionary.Add(currentKey,“”);
}
似乎编写这段代码的人已经使用过字典,即使不需要(只有键用于存储唯一值列表),因为它比用于搜索的myType对象列表快。 这似乎显然是错误的,因为这只是字典的关键,但我正在努力理解什么是修复它的最佳方法

问题:

1)我似乎明白,即使只使用.NET 3.5哈希集,我也能获得很好的性能提升。这是正确的吗?

2)在.NET 2.0中优化上述代码的最佳方法是什么?为什么?

编辑
这是我正在尝试优化的现有代码,它在成千上万个项目中循环,每一个项目都调用一个ContainsKey。一定有更好的方法(即使是在.NET2.0中)!:)

我想你需要把这个问题分解成两个问题

Dictionary
是否是此场景的最佳可用类型 不可以。根据您的细分,
HashSet
显然是更好的选择,因为它的使用模式更符合场景

切换到
Hashset
会提高性能吗? 这是非常主观的,只有剖析者才能给你这个问题的答案。您可能会看到集合中每个元素的内存大小都有很小的改进。但就原始计算能力而言,我怀疑你会看到巨大的差异。只有探查器才能告诉您是否有

在对代码进行与性能相关的更改之前,请记住黄金法则

在分析器准确地告诉您代码的错误之前,不要进行任何与性能相关的更改

做出违反此规则的更改只是猜测。探查器是衡量性能修复成功与否的唯一方法

1)否。字典对键进行哈希运算,因此您的查找应该是O(1)。不过,哈希集应该会减少所需的内存。但老实说,这并没有让你真正看到性能的提升

2) 请给我们更多的细节,告诉我们你想要完成什么。你发布的代码非常简单。你量过尺寸了吗?你看到这个方法很慢吗?不要忘记“我们应该忘记小效率,比如说97%的时间:过早优化是万恶之源。”——Donald Knuth

  • 根据钥匙的大小,您实际上可以

  • 在2.0中,一种方法是尝试插入它并捕获异常(当然,这取决于您计划的重复键数:

  • 我可以看到一个明显的错误(如果我们讨论性能),那就是调用ContainsKey然后添加键值对时做了双重工作。当使用Add方法添加键值对时,会再次在内部检查键值是否存在。整个if块可以安全地替换为:

    。。。 myDictionary[currentKey]=“”;


    如果该键已经存在,则该值将被替换,不会引发任何异常。此外,如果该值根本没有使用,我个人将使用空值来填充它。我看不出有任何理由在那里使用任何字符串常量。

    scottm提到的可能性能降低不是因为进行简单的查找。它是针对c的计算两个集合之间的交集。HashSet的查找速度确实比Dictionary快一些。不过,正如大家所说,性能差异实际上非常小——查找占用了大部分时间&创建KeyValuePair只需很少的时间

    对于2.0,可以将“值”对象设置为以下对象之一:

    public struct Empty {}
    
    它可能比“”略胜一筹

    或者您可以尝试在2.0项目中引用System.Core.dll,以便使用哈希集


    另外,请确保GetHashCode和Equals对MyType尽可能有效。我曾经因为在GetHashCode非常慢的事情上使用字典而被咬过(我相信我们试图使用委托作为键或类似的东西)。

    @Rex,我把它做得更大了一点:)+1同意。最后一句话是帖子中最重要的部分如果这是.NET 2.0,那么
    字典
    可能是最好的选择,因为
    哈希集
    仅在.NET 3.5中添加。@divo,这取决于您添加的键的数量以及您是否计划使用重复的键。ContainsKey()方法每次都会迭代字典中的每一项,因此随着字典的增长,“simple if”可能会成为一大亮点。如果您不打算拥有副本,那么就不会对控制流使用异常,因为您不希望抛出异常。在这种情况下,它可能比if更便宜。我期待重复,我需要过滤掉它们-捕获异常,即使将其用于流控制是错误的,听起来比每次调用ContainsKey要好(大多数项目不会重复),但是它会提高性能吗?你应该遵循JaredPar在这个问题上的建议。如果这部分代码已经明显影响了性能,您可以尝试更改,看看是否有收获。谢谢-我知道过早优化是不好的。这是我正在尝试优化的现有代码,它在成千上万个项目中循环,每一个项目都调用一个ContainsKey。一定有更好的方法做这件事!:)你应该进一步完善你的编辑。你为什么要在成千上万的物品中循环?你能把它并行化吗?我从一堆文件中得到一个可能有重复的对象列表,然后循环遍历这些项目并将它们添加到
    public struct Empty {}