Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.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# 两个字典检索与一个键检索的性能比较_C#_.net - Fatal编程技术网

C# 两个字典检索与一个键检索的性能比较

C# 两个字典检索与一个键检索的性能比较,c#,.net,C#,.net,我有一段遗留代码,其中经常有字符串字典到字符串字典到某个对象的模式 Dictionary<string, Dictionary<string, someobject>> 字典 然后,对象的检索始终基于两倍的TryGetValue Dictionary<string, Dictionary<string, Dealer>> dicDealers ... if (dicDealers.TryGetValue(lab, out dealers))

我有一段遗留代码,其中经常有字符串字典到字符串字典到某个对象的模式

Dictionary<string, Dictionary<string, someobject>>
字典
然后,对象的检索始终基于两倍的TryGetValue

Dictionary<string, Dictionary<string, Dealer>> dicDealers ...

if (dicDealers.TryGetValue(lab, out dealers))
  dealers.TryGetValue(dealerNumber, out dealer);
字典经销商。。。
if(DICTERLERS.TryGetValue(实验室、外部经销商))
经销商.TryGetValue(经销商编号,超出经销商);
现在我在想,如果将两个字符串键组合成一个包含两个字符串成员的键结构,那么一次检索对象应该会更有效。因此,我创建了一个密钥结构,它覆盖GetHashCode并等于在bots密钥成员上计算哈希

public struct Key<T>
{
    private T mKey1;
    private T mKey2;

    public Key(T t, T u)
    {
        mKey1 = t;
        mKey2 = u;
    }

    public override bool Equals(object obj)
    {
        if (obj == null) return false;

        Key<T> rhs = (Key<T>)obj;

        return mKey1.Equals(rhs.mKey1) && mKey2.Equals(rhs.mKey2);
    }

    public override int GetHashCode()
    {
        int hash = 17;

        hash = ((hash << 5) - hash) + mKey1.GetHashCode();
        hash = ((hash << 5) - hash) + mKey2.GetHashCode();
        return hash;
    }
}
公共结构密钥
{
私人T mKey1;
私人T mKey2;
公钥(T,T u)
{
mKey1=t;
mKey2=u;
}
公共覆盖布尔等于(对象对象对象)
{
if(obj==null)返回false;
键rhs=(键)obj;
返回mKey1.Equals(rhs.mKey1)和&mKey2.Equals(rhs.mKey2);
}
公共覆盖int GetHashCode()
{
int hash=17;

hash=((hash您正在尝试改进一种分摊了O(1)复杂度的方法。这是一项艰巨的任务,您永远无法获得比O(1)更高的效率,没有一种算法是O(1/x)

唯一可以改进的是Oh。字典的Oh取决于GetHashCode()的成本和散列代码的分布情况。你又在打一场很难取胜的战斗。String.GetHashCode()是用它编写的,并且生成了一个非常好的散列

事实上,您并没有提高GetHashCode()的效率,它的成本与原始版本中两个GetHashCode()调用的成本相同。因此,是的,您当然应该期望您的版本花费同样多的时间


尝试生成一个更好的版本是不可能的。你必须对字符串有专门的知识,比如知道一个好的散列只需要第一个字符,这样你就可以在计算整个字符串的散列时走捷径。这很少见,也有点危险,散列代码分布不好是有害的。最重要的是,我T是不必要的。你犯的核心错误是试图改进那些不需要改进的代码。只有当一个分析器告诉你TyGETValueValo()时,才会考虑这样做。是关键代码。

是否存在性能问题?如果没有,请优先考虑可读性,将目录封装在一个新类中,使用方法检索项目可能是有意义的,这样您就不必在代码中乱调用TryGetValue。这也是为了可读性。是的,但这不是问题所在。问题是什么?您是如何验证的fy这两种方法都“差不多一样快”?我注意到使用
new key=key1+“-”+key2
而不是保留多个嵌套字典很容易维护。你必须仔细选择分隔符。我省略了部分,它也是为了可读性。但是好吧,优化O(1)相当困难是的
Key<string> key = new Key<string>(lab, dealerNumber);

if (dicDealers.TryGetValue(key, out someobject))
{
...
}