В этом цикле foreach создается мусор? - PullRequest
4 голосов
/ 10 июня 2011

Я столкнулся с методом изменения списка в цикле foreach путем преобразования в сам по себе список следующим образом:

foreach (var item in myList.ToList())
{
     //add or remove items from myList
}

(Если вы попытаетесь изменить myList напрямую, будет выдано сообщение об ошибке, поскольку перечислитель в основном блокирует его)

Это работает, потому что это не оригинал myList, который изменяется. Мой вопрос заключается в том, создает ли этот метод garbage после завершения цикла (а именно из List, возвращаемого методом ToList? Для небольших циклов было бы предпочтительнее использовать for loop, чтобы избежать мусора?

Ответы [ 5 ]

5 голосов
/ 10 июня 2011

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

Стоит ли переходить на for?Возможно, , если , вы можете указать, что эта область кода является узким местом производительности.В противном случае используйте код для простоты и удобства обслуживания.

3 голосов
/ 10 июня 2011

Да. ToList() создаст другой список, который нужно будет собрать мусором.

1 голос
/ 10 июня 2011

Да, метод ToList() создает «мусор».Я бы просто проиндексировал.

for (int i = MyList.Count - 1; 0 <= i; --i)
{
    var item = MyList[i];
    //add or remove items from myList
}
1 голос
/ 10 июня 2011

Это интересная техника, о которой я буду помнить в будущем! (Не могу поверить, я никогда не думал об этом!)

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

  1. Увеличено использование памяти (построение List, отдельно от IEnumerable). Возможно, это не так уж важно, если вы не делаете это очень часто, или IEnumerable очень большой.
  2. Снижена скорость, так как он должен пройти через IEnumerable сразу, чтобы построить List.
  3. Кроме того, если перечисление IEnumerable имеет побочные эффекты, все они будут вызваны этим процессом.

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

0 голосов
/ 10 июня 2011

Это недетерминированный. Но ссылка, созданная из вызова ToList(), в конечном итоге будет GCd.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...