【问题标题】:Dictionary object performance字典对象性能
【发布时间】:2011-12-14 09:21:21
【问题描述】:

我有一个可能的实现方案,我需要一个包含 3 个变量的字典对象。方言、查询名称和查询字符串。在这个阶段我应该注意,编写单独的类对象不是一种选择。

我的问题是以下哪项表现更好。

A) 将前两个变量作为复合键的单个字典对象,例如"dialect,queryname" 和第三个变量作为值。

private Dictionary<string, string>

B) 一个字典对象,它有另一个字典对象作为值,所以第一个变量将是主字典对象的键,第二个变量将是第二个字典对象的键,最后第三个变量将是第二个字典对象的值。

private Dictionary<string, Dictionary<string, string>>

似乎很明显,但编译器是一个神秘的东西,所以我想我应该问你们。

谢谢

【问题讨论】:

  • IDictionary&lt;string, IDictionary&lt;string, string&gt;&gt; dic = new Dictionary&lt;string, Dictionary&lt;string, string&gt;&gt;
  • 我很好奇 - 为什么不写另一个类?

标签: c# .net generics dictionary


【解决方案1】:

只是为了自娱自乐..

             Dictionary<string, string> md1 = new Dictionary<string,string>();
             Dictionary<string, Dictionary<string, string>> md2 = new Dictionary<string, Dictionary<string, string>>();

             Stopwatch st = new Stopwatch();

             st.Start(); 

             for (int i = 0; i < 2000000; i++)
             {
                 md1.Add(i.ToString(), "blabla"); 
             }

             st.Stop();

             Console.WriteLine(st.ElapsedMilliseconds);

             st.Reset();

             st.Start(); 

             for (int i = 0; i < 2000000; i++)
             {
                 md2.Add(i.ToString(), new Dictionary<string, string>()); 
             }

             st.Stop();

             Console.WriteLine(st.ElapsedMilliseconds);

             Console.ReadLine(); 

输出:

831
1399

【讨论】:

  • 不错。但是您只是在这里测试对象的创建,而不是数据检索。
  • 是的。你可以很容易地安排检索时间。
【解决方案2】:

只要您确定“方言,查询名称”键是唯一的,我认为第一个解决方案更快。在第二个中,您必须再进行一次字典查找,这可能比字符串连接更昂贵。

【讨论】:

  • 是的,我 100% 确信这些键将是完全唯一的。这是我的想法,但我想确定一下。感谢您的回复。
【解决方案3】:

你为什么不使用:

Dictionary<string, KeyValuePair<string, string>>

我认为比两者都好。

【讨论】:

  • 你可以在 .NET 4.0 中使用Tuple&lt;string,string&gt;
【解决方案4】:

这不是性能问题,因为两者具有完全不同的语义。

第一个为您提供了一种使用一个对象来查找另一个对象的方法。

第二种方法为您提供了一种使用一个对象来查找另一个对象的方法,您可以在其中使用另一个对象来查找第三个对象。

在以后如何扩展这些功能方面略有不同。

一般来说,我会使用Dictionary&lt;Tuple&lt;string, string&gt;, string&gt;。这会给我一个组合键,显然是一个组合键。

实际上,这不是真的,我会创建一个新类。这怎么不是一个选择?不过,如果这是家庭作业并且“不要创建新课程”是问题的一部分,我会使用Dictionary&lt;Tuple&lt;string, string&gt;, string&gt;

编辑:

class DialectQuery : IEquatable<DialectQuery>
{
  public Dialect{get;private set}
  public Name{get;private set;}
  public DialectQuery(string dialect, string name)
  {
    Dialect = dialect;
    Name = name;
  }
  public bool Equals(DialectQuery other)
  {
    return other != null && Name == other.Name && Dialect == other.Dialect;
  }
  public override bool Equals(object other)
  {
    return Equals((object)other);
  }
  public override int GetHashCode()
  {
    int dHash = Dialect.GetHashCode();
    return (dHash << 16 | dHash >> 16) ^ Name.GetHashCode();
  }
}

到目前为止,它的行为与 Tuple 完全相同。现在,如果我收到一个更改请求,即方言必须不区分大小写但查询名称区分大小写,或者方言是代码,因此需要不变的比较,但名称是人工输入的,因此需要区分文化的比较,或其他任何东西,我要做两个简单的更改。

YAGNI 不适用,它不是在“以防万一”对大型对象进行编码,而是定义了一个很好的“好吧,我可能不需要它,但如果我这样做了,它会去这里”的点。

【讨论】:

  • 如果您要使用一个类,您将如何构建它以便能够在提供相同功能的同时产生相同或更好的性能?我需要能够构建它并使用所有三个变量(数据库中的表中的一个以上)填充它,然后能够使用两个关键变量快速选择查询字符串。对我来说,使用我提到的第一个选项似乎要简单得多。
  • 作为一个具有两个属性和一个相等覆盖的简单类。这是半分钟的编码,但很好地处理了“哦,方言应该不区分大小写,但查询不应该”或规范中出现的任何其他扩展。
  • 这对我的场景到底有什么作用?如果我需要有效地生成可以通过两个键访问的 sql 命令列表?我想使用字典对象的原因是,一旦在实例化我的 sql 工厂类时填充了所有必要的方言、查询名称和查询,我就可以通过检查方言和查询名称的复合键来访问我需要的任何查询。可能只是我的大脑一天很慢,但我看不出如何使用课程来做到这一点?所有三个变量都像这样的方言>查询名称>查询链接。你怎么能用属性做到这一点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-17
  • 1970-01-01
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
  • 2011-02-14
  • 2010-11-21
相关资源
最近更新 更多