C #, какой метод кодирования быстрее? - PullRequest
0 голосов
/ 02 октября 2009
public static Dictionary<string,List<LookupItem>> dict;

if (dict == null)
{
   dict = IsolatedStorage.GetDropDowns();
   return dict["Priority"]
}
else
   return dict["Priority"];

или

try
{
   return dict["Priority"];
}
catch(KeyNotFoundException e)
{
   dict = IsolatedStorage.GetDropDowns();
   return dict["Priority"];
}

Это приложение Silverlight, у меня есть раскрывающиеся списки, кэшированные в изолированном хранилище (если мне нужно было запрашивать службу wcf для каждого поиска, тогда сетка данных появляется вечно, я хорошо знаю, что раскрывающиеся списки могут устареть, и у меня есть средство обновление словаря, когда новые значения добавляются / удаляются через обратный вызов), в моем xaml у меня есть конвертер, который преобразует Id, возвращенный из dbquery, в связанный объект LookupItem. Я знаю, что я никогда не должен использовать try и catch как часть логики приложения, но мне действительно нужен самый быстрый из возможных подходов, поэтому я готов игнорировать эту архитектурную нет-нет. Причина, по которой словарь станет нулевым, заключается в том, что при сохранении словаря в качестве статической переменной в произвольном классе, если пользователю нужно нажать клавишу F5, чтобы обновить страницу, словарь потеряет свои значения, поскольку файл xap перезагружается и моя страница кэширования то, что выполняется при входе в систему, не будет выполнено. «Приоритет» содержит список. LookupItem содержит ключ / значение, необходимые для ComboBox и т. Д.

1) Является ли словарь наиболее эффективным способом хранения этой информации? 2) какой из двух подходов даст максимально быстрый возврат списка?

Ответы [ 3 ]

8 голосов
/ 02 октября 2009

Ну, для начала вам не хватает скобок, но я бы написал это так:

if (dict == null)
{
   dict = IsolatedStorage.GetDropDowns();
}
return dict["Priority"];

Обратите внимание, что вам, вероятно, потребуется некоторая блокировка, чтобы сделать этот потокобезопасным. На самом деле, почему бы просто не написать это как:

public static Dictionary<string,List<LookupItem>> dict 
    = IsolatedStorage.GetDropDowns();

для начала? Тогда вы знаете, что он никогда не будет нулевым.

В любом случае, пожалуйста, не используйте вторую идею. Проверка на ничтожность безумно быстра, и в любом случае вы все равно не справитесь с NullReferenceException вместо KeyNotFoundException ...

Если вы действительно хотите вести себя по-разному в зависимости от того, присутствует или нет ключ, вы должны использовать (при условии, что dict уже не равен нулю):

List<LookupItem> list;
if (!dict.TryGetValue("Priority", out list))
{
    // Deal with the key being missing
}
else
{
    return list;
}

Я бы также поставил под сомнение ваше мнение о том, что этот подход должен быть "максимально быстрым" - после того, как вы убедились, что выполняете выборку из WCF только один раз, вы уверены, что действительно производительность горлышко бутылки? Я был бы шокирован, если бы это было так.

1 голос
/ 02 октября 2009

Помимо того, что в вашем первом примере отсутствуют некоторые фигурные скобки, он будет намного быстрее, потому что выражение if выполняется практически мгновенно, в то время как генерируется исключение, создаются необходимые обработчики и выполняется обход стека немного больше работы для CLR ...

Так что, если вы называете поле 'dict' меньше, чем, скажем, 500.000 раз, это однозначно # 1. Относительно вашего первого вопроса: я не совсем уверен, потому что я не герой WPF, но обычно для такого рода данных редко есть что-то более эффективное, чем словарь.

И, между прочим: Вы не получите «KeyNotFoundException» в вышеупомянутом случае, но «NullReferenceException» ...

1 голос
/ 02 октября 2009
  1. словарь выглядит как разумный подход к хранению данные.
  2. Ваши два примера кода тестируют разные вещи. Чтобы убедиться, что dict не равно нулю, см. Ответ Джона.

Лучшая альтернатива try / catch (KeyNotFoundException) - TryGetValue:

List<LookupItem> priority = null;
if(!dict.TryGetValue("Priority", out priority))
    throw new ApplicationException("Could not find Priority list.");

return priority;
...