【问题标题】:Which of the two usage patterns regarding Dictionary should be preferred in general?一般来说,应该首选关于 Dictionary 的两种使用模式中的哪一种?
【发布时间】:2016-06-20 03:31:39
【问题描述】:

在我一直在研究的代码库中,我发现使用模式是这样的:

If (dict.ContainsKey(key)) // dict is of type IDictionary
{
  throw ...;
}
else
{
  dict.Add(key, …);
}

这涉及两个搜索过程调用 (ContainsKey + []/Add),无论代码采用哪个分支。我想知道以下模式是否会更有效并且通常应该是首选。它只涉及一个搜索过程调用,但额外依赖异常系统工作,预计会有一些运行时开销。

try
{
  dict.Add(key, …);
}
catch (ArgumentException)
{
  throw ...;
}

【问题讨论】:

  • 应为特殊情况保留例外。我觉得字典中的冲突是意料之中的事情,所以这对我来说就像是在滥用异常系统。
  • 旁注:你知道catch { throw; } 什么都不做吗?
  • 如果你追求效率,你应该避免任何投掷或捕捉的东西。异常处理代码比非异常代码慢许多数量级。您应该阅读 Eric Lippert 关于异常的优秀文章 - ericlippert.com/2008/09/10/vexing-exceptions
  • 如果您真的想要这个问题的可靠答案,您应该向我们提供minimal reproducible example。然后我们可以对所有可能的方法进行测试和基准测试。
  • @Enigmativity 取决于你投掷的频率。在某些时候,每次检查的开销将大于仅仅抛出失败的成本。

标签: c# performance exception dictionary


【解决方案1】:

如果在 IDictionary 中已经存在 key 时无法满足函数的后置条件(这意味着返回并继续运行程序的当前流程是不安全的),那么一定要采用后一种方法。少了一次查找,一条“快乐路径”几乎没有运行时成本,也没有机会意外误用/丢弃“错误代码”返回值。

如果发生这种情况,我假设您需要抛出特定的异常类型或消息。否则,只需松开 try...catch 块。

【讨论】:

    猜你喜欢
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多