2010-08-04 3 views
17

Когда-то я изучал преимущества неизменной строки из-за чего-то, чтобы улучшить производительность в памяти.В чем преимущество непрерывности String?

Может кто-нибудь объяснить это мне? Я не могу найти его в Интернете.

+1

Возможный дубликат [Что подразумевается под неизменным?] (Http://stackoverflow.com/questions/279507/what-is-meant-by-immutable). Хотя название этого вопроса не одно и то же, оно включает вопрос о преимуществах и недостатках, которые, по крайней мере, один из ответов (по Имагисту) достаточно хорошо освещен. –

ответ

5

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

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

9

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

34

Неизменность (для строк или других типов) могут иметь многочисленные преимущества:

  • Это делает его легче рассуждать о коде, так как вы можете сделать предположения относительно переменных и аргументов, которые вы не можете иначе делать.
  • Это упрощает многопоточное программирование, поскольку чтение из типа, которое не может изменение всегда безопасно делать одновременно.
  • Это позволяет сократить использование памяти, позволяя объединять одинаковые значения и ссылаться на несколько мест. Как Java, так и C# выполняют интернирование строк, чтобы уменьшить стоимость памяти для литеральных строк, встроенных в код.
  • Он упрощает проектирование и реализацию определенных алгоритмов (например, тех, которые используют обратное отслеживание или разделение пространств значений), поскольку ранее вычисленное состояние может быть повторно использовано позже.
  • Неизменность является основополагающим принципом во многих функциональных языках программирования - это позволяет рассматривать код как последовательность преобразований из одного представления в другое, а не последовательность мутаций.

Неизменяемые строки также помогают избежать искушения использовать строки в качестве буферов. Многие недостатки в программах на C/C++ связаны с проблемами переполнения буфера, возникающими в результате использования массивов голых символов для составления или изменения строковых значений. Обработка строк как изменчивых типов поощряет использование типов, более подходящих для манипуляции с буфером (см. StringBuilder в .NET или Java).

+1

Но если вы используете парадигму [Copy-On-Write] (http://en.wikipedia.org/wiki/Copy-on-write), у вас есть преимущества непреложных строк * и * личных копий и на месте модификация, если необходимо, например для быстрого анализа. «StringBuilder» - это всего лишь обходное решение для замедления непреложной конкатенации строк и небольшой пользы в отношении шаблона COW, связанного с эффективной системой управления кучей. COW позволяет обеспечить безопасный доступ к вашему буферу * и * быстро в одно и то же время. –

+0

Некоторые из этих аргументов кажутся запутанными параметрами «const» (такими же, как Java «final») с неизменностью упомянутых объектов. –

+0

@LBushkin. Несмотря на то, что вы делаете некоторые аргументы в своих пунктах, ваш пункт «Неизменяемые строки также помогают избежать ...» является вводящим в заблуждение. StringBuilder решает совершенно другую проблему, чем переполнение буфера в C - это просто оптимизация для конкатенации строк, поскольку конкатенация неизменяемых строк происходит медленно - вам нужно создать два новых объекта и скопировать все символы для каждого шага конкатенации. – Alexey

0

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

0

a) Представьте себе объект StringPool, не делая строку неизменной, ее невозможно вообще, поскольку в случае пула строк один строковый объект/литерал, например. «Тест» ссылается на множество ссылочных переменных, поэтому, если какой-либо из них изменит значение, то другие будут автоматически затронуты, т. Е. Скажем Строка A = «Тест» и строка B = «Тест» Теперь String B называется «Test» .toUpperCase(), которые изменяют один и тот же объект в «TEST», поэтому A также будет «TEST», что нежелательно.
b) Еще одна причина того, почему String неизменна в Java, - это позволить String кэшировать свой хэш-код, будучи неизменяемым. String в Java кэширует свой хэш-код и не вычисляет каждый раз, когда мы вызываем метод hashcode String, что делает его очень быстрым, как hashmap ключ.

0

Возможно, мой ответ устарел, но, вероятно, кто-то найдет здесь новую информацию.

Почему Java Строка неизменна и почему это хорошо:

  • вы можете разделить строку между потоками и быть уверенным, что никто из них не изменит строку и запутать другую нить
  • вы не нужен замок. Несколько потоков могут работать с неизменяемой строкой без конфликтов
  • Если вы только что получили строку, вы можете быть уверены, что никто не изменит ее значение после этого
  • вы можете иметь много дубликатов строк - они будут направлены на один экземпляр, до одной копии. Это экономит память компьютера (ОЗУ)
  • вы можете делать подстроку без копирования, создавая указатель на существующий элемент строки. Поэтому реализация операции подстроки Java настолько быстро
  • неизменяемые строки (объекты) гораздо лучше подходят для использования их в качестве ключа в хэш-таблиц
0

Фундаментально, если один объект или метод желает передать информацию другим есть несколько способов, он может сделать это:

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

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

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

  4. Он может возвращать ссылку на неизменяемый объект, содержащий информацию.

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

Смежные вопросы