Подтвердить что ты не робот

Объявит ли переменная внутри/вне цикла изменение производительности?

Это:

foreach(Type item in myCollection)
{
   StringBuilder sb = new StringBuilder();
}

намного медленнее, чем:

StringBuilder sb = new StringBuilder();

foreach(Type item in myCollection)
{
   sb = new StringBuilder();
}

Другими словами, будет ли действительно важно, где я объявляю свой StringBuilder?

4b9b3361

Ответ 1

Возможно, вы можете получить некоторую производительность, если вы напишете это:

StringBuilder sb = new StringBuilder();
foreach(Type item in myCollection)
{
   sb.Length = 0;
}

Итак, вам нужно создать экземпляр StringBuilder только один раз и reset размер в цикле, который должен быть немного быстрее, чем создание экземпляра нового объекта.

Ответ 2

Нет, это не имеет значения, если вы заявите об этом.

Для общей чистоты кода вы должны объявить его во внутренней области, которую он использует, т.е. ваш первый пример.

Ответ 3

Во втором примере вы создаете дополнительный экземпляр StringBuilder. Кроме того, они оба одинаковы, поэтому проблема с производительностью является несущественной.

Ответ 4

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

Ответ 5

Эффективная разница между двумя вашими образцами кода заключается в том, что вторая будет выделять еще один экземпляр StringBuilder, чем первый. Эффект производительности этого по сравнению с остальной частью вашего приложения практически не имеет значения.

Ответ 6

Лучший способ проверить - попробовать оба метода в цикле, по 100 000 каждый. Измерьте количество времени, затрачиваемого каждые 100 000 итераций, и сравните их. Я не думаю, что есть большая разница. Но есть небольшая разница. Первый пример будет иметь столько переменных, сколько количество итераций. Второй пример имеет только одну переменную. Компилятор достаточно умен, чтобы сделать некоторые оптимизации здесь, поэтому вы не заметите улучшения скорости. Однако, если вы не хотите использовать последний объект, сгенерированный внутри цикла, как только вы снова окажетесь за пределами цикла, то первое решение будет лучше. Во втором решении требуется некоторое время, прежде чем сборщик мусора освободит последний созданный объект. В первом примере сборщик мусора будет немного быстрее освобождать объект. Это зависит от остальной части кода, но если вы храните большое количество данных в этом объекте StringBuilder, второй пример может задерживаться в этой памяти намного дольше, тем самым снижая производительность вашего кода после выхода из цикла!
Опять же, если объекты съедают 100 КБ, а у вас есть 16 ГБ на вашем компьютере, никто не заботится... Сборщик мусора в конечном итоге освободит его, возможно, как только вы покинете метод, который содержит этот цикл.

Ответ 7

Если у вас есть другие аналогичные сегменты кода типа, вы всегда можете просмотреть или поместить некоторые таймеры вокруг кода и запустить тест типа теста, чтобы убедиться сами. Другим фактором будет область памяти, о которой другие комментируют.