Считайте, что стажировка - это оптимизация;он обменивает снижение одних желательных качеств на увеличение других.В частности, интернирование обладает следующими хорошими качествами:
- Память не тратится впустую на дублирующиеся строки.
- Сравнение равенства между строками, известными как интернируемым, очень быстро.
- Сравнение равенства между строками, которые оказались интернированными, все еще намного быстрее, чем если бы они не интернировались.
- В некоторых случаях другие сравнения дают выигрыш в производительности.
Он имеетследующие плохие качества:
- Строки не собираются мусором так часто (если вообще), поэтому память, которую можно восстановить, используется для строк, которые больше никогда не видны, или в течение очень долгого времени.(Слушайте все свои строки, и вы можете использовать очень неприятное использование памяти.)
В качестве оптимизации мы используем его там, где либо хорошие качества превосходят плохие, либо плохие.не удерживается (если мы знаем, что строка все равно будет существовать на протяжении всего жизненного цикла приложения, или знаем, что она будет использоваться много раз, то плохая часть не сохраняется).
То же самое мы не используем, когда плохие качества перевешивают хорошие.(Большую часть времени).
IsInterned()
можно использовать для нахождения промежуточной точки.
Предположим, у меня есть строковое свойство Name
:
public string Name { get; set; }
Допустим, я знаю, что обычно ищут объекты с заданным Name
, или пытаются найти объекты с одинаковым Name
, или иным образом проводят много сравнений на равенство.ИЛИ Допустим, я знаю, что будет много других объектов с таким же Name
.ИЛИ оба.
В этих случаях я мог бы рассмотреть возможность стажировки:
private string _name;
public string Name
{
get { return _name; }
set { _name = string.Intern(value); }
}
Конечно, было ли это хорошей идеей или нет, зависит от хороших и плохих качеств интернирования, упомянутых выше.
Между использованием и неиспользованием есть возможность:
private string _name;
public string Name
{
get { return _name; }
set { _name = string.IsInterned(value) ?? value; }
}
Здесь, если строка value
уже интернирована, то мы с обратной стороны интернирования уже работаем, и мыбольше не страдаем, поэтому мы пользуемся этим.Но если value
еще не интернирован, то мы просто используем его как есть.
Это также оптимизация, которая оптимизирует для другого случая.Это полезно только в том случае, если разумное количество видимых значений может быть интернировано каким-либо другим кодом (или потому что они соответствуют литералам в сборке), в противном случае это просто тратит время на поиск.Это, вероятно, менее полезно, чем Intern()
, что, в свою очередь, менее полезно, чем просто использование строк и игнорирование интернирования, но это показывает время, когда это может быть полезно.