Уменьшает ли «readonly» (C #) использование памяти? - PullRequest
12 голосов
/ 20 июля 2009

В C # установка поля как только для чтения уменьшает использование памяти?

т.е.

DBRepository _db = new DBRepository();

против

readonly DBRepository _db = new DBRepository();

Просто любопытно. Спасибо.

Ответы [ 5 ]

19 голосов
/ 20 июля 2009

номер

Это означает, что вы не можете назначить его, кроме как в точке объявления или в конструкторе. Вы также не можете передать его как параметр ref или out методу.

Редактировать: на основе комментария ниже. Следующее поле readonly, потому что вы хотите, чтобы вызывающие абоненты имели прямой доступ на чтение к string.Empty, но вы не хотите, чтобы они устанавливали его на что-то другое.

public sealed class String
{
    public static readonly string Empty = "";
}

Кроме того, иногда, когда у меня есть List<> или Dictionary<> в качестве поля в классе, я объявляю его readonly, чтобы указать, что я хочу работать с его членами (даже Добавить и удалить элементы и т. Д.) .) но я никогда не хочу назначать ему другой объект List или Dictionary.

Еще одно редактирование: убедитесь, что вы прочитали о устаревшем поле Path.InvalidPathChars (в разделе замечаний), чтобы показать серьезную проблему, которая может возникнуть, если вы не понимаете, что такое readonly, и нет.

5 голосов
/ 20 июля 2009

ДА!

Да? Да! Как? Просто. Поле только для чтения не может получить новое значение, поэтому вы не можете создать второй DBRepository и назначить его этому полю. Если это не только для чтения, то вы можете написать код, который переназначит новое значение для этого поля. И в период между переназначением и временем, когда сборщик мусора очистит ваше старое значение, у вас будет немного больше используемой памяти. Кроме того, если при очистке DBRepository произошла утечка памяти, переназначение новых значений этому полю вызовет множественные утечки памяти.

Ситуация, когда может произойти такая утечка памяти, такова: 1) Вы присваиваете значение _db. 2) Вы присваиваете значение _db другому полю. 3) Вы переназначаете новое значение на _db. В этот момент у вас будет два объекта DBRepository в памяти, потому что на старый объект все еще ссылаются из другого объекта. Таким образом, старый объект не будет освобожден, пока второе поле не освободит его.

Но это очень придирчиво и довольно редко. Ответ «Нет» более уместен. Не используйте «ReadOnly» для экономии памяти, потому что вы будете использовать ее по неправильной причине. Используйте «ReadOnly», чтобы другие не переназначали значение этому полю. (По сути, я говорю, что может уменьшить использование памяти ...)

5 голосов
/ 20 июля 2009

Нет. readonly и const в основном служат одной и той же цели: предотвратить присвоение значений во время выполнения. Тем не менее, они имеют семантически различное использование.

только чтение по сравнению с константой

Поле const вычисляется во время компиляции и может быть инициализировано только при объявлении, тогда как поле readonly оценивается во время run и может быть инициализировано как в конструкторы и на сайте декларации.

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

0 голосов
/ 16 октября 2012

Ответ «Нет» написан с точки зрения хорошего кодировщика, ориентированного на производительность, который уже знает все хитрости и ловушки, например ::10000

  1. Нет LINQ в тесных петлях. В самом деле. Никто. Когда-либо.
  2. Приведите ваши перечисления к целым числам перед сравнением
  3. Остерегайтесь структур типа значения
  4. «новый» - это новый Грю
  5. CLRProfiler - твой друг
  6. Другие профилировщики помещают переменное время строительства в странные места

Ответ «Да» очень важен для кодировщика, который не знает о подводных камнях в дизайне C #, или для того, кто проглотил кулер «Профилирование - зло».

Я инициализирую множество (возможно, даже МНОГО) матриц и массивов в нашем коде. Я заметил, что ленивая инициализация с: if (переменная == ноль) // variable = new Variable ()

кажется менее производительным, чем предварительное построение. Поскольку readonly вынуждает вас создавать в конструкторе, вы получаете преимущества локализации данных в памяти и не позволяете вам выполнять другие катастрофические операции «сборки и замены во время выполнения». C # может ужасно подавиться сборщиком мусора.

C # позволяет нам очень легко писать ужасно неэффективный код памяти. malloc был способом заставить нас задуматься о (де) распределении. Точно так же, только чтение заставляет нас думать об этом.

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

Тем не менее, если вы не пишете код HPC, то преждевременная оптимизация является корнем всех знаний об архитектуре машины. О нет, подожди ... Я имел в виду зло, согласно стандартной доктрине. Все приветствуют стандартную доктрину.

0 голосов
/ 20 июля 2009

readonly полезно в том случае, если вы хотите использовать объект в качестве ключа. Этот ключ не должен изменяться, иначе вы не сможете получить доступ к тому, к чему он предоставляет доступ.

Например; 1) с событиями на сайте ASP.NET вы можете использовать коллекцию Events в элементе управления. В вашем контроле вы бы оставляли поле объекта только для чтения, чтобы ссылаться на обработчики событий в коллекции. 2) В многопоточности может потребоваться синхронизировать доступ. Это можно сделать, чтобы объединить оператор блокировки с объектом, доступным только для чтения, для блокировки.

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