C#, объявляя переменную внутри for..loop, это снизит производительность? [дубликат]

этот вопрос уже есть ответ здесь:

например:

            for (i = 0; i < 100; i++)
            {
               string myvar = "";
                // Some logic
            }

это делает performace или утечку памяти?

почему я это делаю, потому что я не хочу " myvar" доступный вне для..петля.

это любой монитор производительности, я могу сравнить время выполнения между двумя фрагментами или всей программой ?

спасибо вам.

8 ответов


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


возможно, вы могли бы проверить старый тест, который я когда-то сделал относительно другого разговора. переменной. Оптимизированный способ

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

мой простой тест. Я инициализировал объект 100,000,000 раз, и, по-видимому, было быстрее создать новый, а не повторно использовать старый: O

    string output = "";
    {
        DateTime startTime1 = DateTime.Now;
        myclass cls = new myclass();
        for (int i = 0; i < 100000000; i++)
        {
            cls = new myclass();
            cls.var1 = 1;
        }
        TimeSpan span1 = DateTime.Now - startTime1;
        output += span1.ToString();
    }

    {
        DateTime startTime2 = DateTime.Now;
        for (int i = 0; i < 100000000; i++)
        {
            myclass cls = new myclass();
            cls.var1 = 1;
        }
        TimeSpan span2 = DateTime.Now - startTime2;
        output += Environment.NewLine + span2.ToString() ;
    }
    //Span1 took 00:00:02.0391166
    //Span2 took 00:00:01.9331106

public class myclass
{
    public int var1 = 0;
    public myclass()
    {
    }
}

Я считаю, что это будет проблемой производительности. Поскольку виртуальной машине нужно будет выделить память для хранения ссылки на строку каждый цикл. Несмотря на то, что ссылка может быть на один и тот же экземпляр String, выделение памяти каждый раз, когда он обходит цикл, не было бы предпочтительным.


обновление:

Если вы используете тот же тип переменной, что и цикл, вы можете сделать то, что я изначально подсластил:

for (int  i = 0,  myvar = 0; i < 100; i++) {
    //some logic
}

в противном случае не беспокойтесь об этом, как другие уже предложили

@phoog, thx для проверки ответа


чтобы обеспечить реальный пример жизни:

Я только что закончила писать .загрузчик модели obj, который, конечно же, содержит некоторые вложенные циклы. Я объявил все мои variabeles над моими петлями, но затем я начал задаваться тем же вопросом, что и OP, и нашел эту нить. Поэтому я попытался переместить все объявления переменных в первую точку цикла, где я их использую, и фактически увидел небольшой прирост производительности. Модель, которая ранее занимала 380 МС в среднем для загрузки (370-400 МС на самом деле) теперь последовательно загружает около 15-20 мс быстрее. Это всего лишь около 5%, но не менее улучшение.

моя конструкция цикла состоит только из цикла foreach и вложенного цикла for, но также содержит много операторов if. Я переехала 5 переменных, большинство из которых являются массивами строк и целых чисел.


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

Я бы рекомендовал вам использовать строковый конструктор, объявленный вне области цикла for.


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

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


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

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