Простой базовый вопрос

#c# #java #windows-phone-7

#c# #java #windows-phone-7

Вопрос:

Извините, что задал такой простой вопрос, но хотел прояснить концепцию.

Ниже приведен мой код, в котором я создаю словарь внутри цикла for

 if(condition)
{
  // some code here
  for(int i=0; i<length; i  )
  {
    Dictionary<string, string> parameter = new Dictionary<string, string>();
    parameter.Add("ServiceTypeID", "1");
    parameter.Add("Description", "disc");
  }
}
  

вместо того, чтобы каждый раз создавать объект dictionary, должен ли я создавать объект dictionary перед циклом for и применять метод clear к объекту dictionary, например

 if(condition)
{
  Dictionary<string, string> parameter = new Dictionary<string, string>();
  // some code here
  for(int i=0; i<length; i  )
  {
    parameter.clear();
    parameter.Add("ServiceTypeID", "1");
    parameter.Add("Description", "disc");
  }
}
  

Какой из этих двух вариантов будет лучше по производительности.

Спасибо, ноль

Комментарии:

1. не могли бы вы объяснить, что вы пытаетесь сделать? ни один цикл не имеет никакого смысла.

Ответ №1:

В большинстве практических сценариев разница близка к нулю.

Можно подумать, что очистка структуры данных выполняется быстрее, чем инициализация пустой. Это не всегда так. Обратите внимание, что в современных языках (C #, Java) диспетчер памяти оптимизирован для выделения множества небольших объектов (это связано с тем, как работают сборщики мусора). В C из-за отсутствия GC диспетчер памяти настроен на выделение нескольких больших объектов. Таким образом, повторное построение словаря внутри цикла сопоставимо (с точки зрения производительности) с его очисткой.

Более того, clear() не обязательно может освободить всю выделенную память. Может быть, это только сбрасывает некоторые указатели / индексы. Следовательно, если вы используете clear(), ваш словарь все еще может занимать большие куски памяти, что может замедлить работу других частей вашего кода.

Итог: не беспокойтесь об этом, если только профилировщик не сказал вам, что это узкое место вашей программы.

Ответ №2:

Если оба этих решения работают для вас, вы должны помнить два пункта :

  • сначала создается объект dictionary в каждом цикле, поэтому его скорость ниже из-за выделения памяти в каждом цикле
  • второй быстрее. но объект Dictionary активируется на большее время, поэтому память будет заполнена, если GC не предпримет над ним никаких действий! (GC удаляет его после завершения области видимости) таким образом, в длинных блоках кода память используется дольше!

Комментарии:

1. .. просто любопытно, но разве clear-call не позволяет GC собирать все пары KeyValuePairs, на которые больше нет ссылок?

2. IIRC утверждение о том, что GC удаляет объект после завершения области видимости, неверно: объект просто помечен для сбора, и фактически никто не имеет особого контроля над действиями GC (кроме использования общедоступных методов GC). Но GC будет предпринимать действия, если есть запросы на память, а память на исходе…

Ответ №3:

В нескольких словах о производительности, очевидно, что второй цикл лучше, потому что вы создаете только один объект, а затем в цикле добавляете элементы.

Однако в первом цикле переменная параметра бесполезна, потому что в конце for она больше не существует…

также во втором цикле у вас возникает та же проблема … в конце, если эта ссылка не может быть использована….