Dictionary ArgumentException 日志重复键:哪个性能更高?

问题描述 投票:0回答:3

这里我添加一些东西到

Dictionary

dictionary.Add(dictionaryKey, value);

如果

dictionaryKey
已经存在,则会抛出
ArgumentException
。它的信息相当笼统:

已添加具有相同密钥的项目。

如果我对

dictionary.Add
的调用位于循环或辅助函数内部,则很难立即判断已添加的哪个键引发了此异常。我想尽快轻松地知道这一点。

有几个选项。

1)

if(dictionary.ContainsKey(dictionaryKey)
{
    throw new ArgumentException($"An item with the same key ({dictionaryKey}) has already been added.");
}

dictionary.Add(dictionaryKey, value);

2)

try
{
    dictionary.Add(dictionaryKey, value);
}
catch(ArgumentException argumentException)
{
    throw new ArgumentException($"An item with the same key ({dictionaryKey}) has already been added.");
}

3)其他方式

我知道设置 try/catch 块会影响性能,但似乎运行

dictionary.ContainsKey(dictionaryKey)
也意味着每次都会进行额外的查找。这些选项中哪个性能最高?

c# dictionary try-catch big-o
3个回答
2
投票

不确定此代码的上下文属于何处,但就性能而言,这取决于您是否期望重复

dictionaryKey

如果存在重复项,我会使用第一种方法,因为

ContainsKey
是 O(1) 操作,而
try
/
catch
如果用于处理控制流,会产生 小的性能损失。据推测,这个惩罚将大于 O(1)。

但是如果你能保证没有重复的

dictionaryKey
,第二种方法会更快。仅当抛出异常(发现重复键)时才会发生
try
/
catch
性能损失。第一种方法将对
ContainsKey
执行不必要的调用。当然,这意味着您不需要首先将代码包装在
try
/
catch
中,从而违背了您问题的目的。

我会选择第一种方法。


0
投票

我想说第一更好。因为当您使用第二种方法时,它将触发运行时错误,这意味着它将在内存中创建一个额外的 Exception 对象,该对象由捕获短语中的变量“argumentException”引用。


0
投票

我参加聚会迟到了,抱歉。

也许您可以在

ArgumentException.Data
属性中添加一个键值对来指示有问题的键?

例如

string key = foo;

try
{
  someDictionary.Add(key, "Hello");
}
catch (ArgumentException e)
{
  e.Data.Add("DuplicateKey", key);
}

您可以通过在

An item with the same key has already been added
块中进行消息比较(例如
catch
)来进一步限定异常。

© www.soinside.com 2019 - 2024. All rights reserved.