Хранение имен значений свойств в виде строковых констант - производительность и использование памяти? - PullRequest
3 голосов
/ 01 августа 2010

Я использую около 1000 свойств, связанных с конкретным java.util.Properties, который поддерживается файлом. Основная причина для файла заключается в том, чтобы изменить их без перекомпиляции программы и позволить пользователям настроить их в соответствии со своими вкусами. Некоторые свойства используются только в одном месте кода, но некоторые свойства используются несколько раз в разных сегментах кода и даже в разных классах.

У меня недавно появилась привычка объявлять все те свойства, которые используются в качестве строковых констант, обычно в отдельном интерфейсе, например:

public interface AnimalConstants {
  public static final String WEIGHT_PROPERTY = "weight";
  public static final String RUNNING_SPEED_PROPERTY = "speedInKph";
  public static final String HOURS_OF_SLEEP_A_DAY_PROPERTY = "sleepHrs";
  ...
}

Когда классу требуется доступ к некоторым свойствам животных, я просто реализую этот интерфейс, и у меня есть доступ ко всем объявленным константам свойств. Когда мне нужно определенное свойство, я просто использую соответствующую константу, не задумываясь о том, каково ее точное имя (поскольку часто используются сокращения), и, что более важно, таким образом устраняется риск неправильного ввода имени свойства. Другое преимущество состоит в том, что если я позже решу переименовать свойство, чтобы сделать его более понятным для опытного пользователя, который настраивает эти свойства), мне просто нужно изменить это имя в интерфейсе, где объявлена ​​эта константа свойства (и, конечно, файл свойств ), поэтому не нужно «искать и заменять» весь проект. Наконец, я могу легко проверить, используется ли свойство или нет; Я просто комментирую это, компилирую код и вижу, есть ли ошибка.

Однако, несмотря на все эти преимущества, мне любопытно, каковы недостатки этого подхода. Больше всего меня интересует следующее:

  • Какое влияние оказывает этот подход (1000 строковых констант) на пул строк? Или они создаются по требованию, когда я получаю доступ к этим константам? Это предотвращает кэширование других строк в пуле строк?
  • Какова стоимость производительности этого подхода по сравнению с той, в которой я использую жестко закодированные строковые константы, она одинакова (без учета стоимости доступа к полю)? Пул строк ведет себя одинаково или сильно отличается?
  • Какое среднее увеличение памяти при таком подходе, все ли строковые константы хранятся в памяти все время?

Любой хороший комментарий / наблюдение приветствуется.

Ответы [ 2 ]

7 голосов
/ 01 августа 2010

Статические поля инициализируются во время фазы инициализации во время загрузки класса.

Но если примитивный тип или строка определены как константа, а значение известно во время компиляции, компилятор заменяет имя константывезде в коде со своим значением.Это называется константой времени компиляции.Если значение константы во внешнем мире изменяется (например, если законодательно установлено, что pi на самом деле должно быть 3,975), вам нужно будет перекомпилировать любые классы, которые используют эту константу, чтобы получить текущее значение.В этот момент будут созданы строковые литералы для уникальных строк, которые определены как значения констант.

Но это похоже на загрузку констант из ресурсов в объекте свойств (написание кода для того же самого).Константы определенно потребляют память.Поведение пула строк не изменится.

Некоторые соображения относительно подхода к проектированию:

Очень легко поместить все константы конфигурации в класс, а затем обращаться к ним по всему приложению.Чтобы изменить константы статической конфигурации, вы изменяете исходный код и перекомпилируете.Что делать, если в какой-то момент в будущем вашей программе потребуется поддерживать более одной конфигурации или чередовать конфигурации, когда она обрабатывает разные файлы, или даже запускать один поток с одной конфигурацией и другой поток с другой конфигурацией.Вы не сможете использовать эту технику.Таким образом, для лучшего дизайна вы храните константы, которые никогда не меняются как статические константы в определении класса. Они загружаются, как только класс загружается в память.В другом случае, который я описал ранее (загрузка ресурсов), вы храните их в различных файлах свойств, которые можно загрузить в объект свойств JAVA.Примерами таких случаев могут быть сведения, связанные с подключением JDBC, и т. Д. *

5 голосов
/ 01 августа 2010

1) Как этот подход (1000 строковых констант) влияет на пул строк?

Объявление имен свойств в качестве строковых констант является правильным решением.Но не будет никаких изменений в «Строковом буквальном пуле».Когда присутствует несколько экземпляров одного и того же литерала, все они просто связаны с одним и тем же элементом в пуле литералов (при условии, что конструктор String не используется).

2) они создаются по требованию, когда я получаю доступ к этим константам?

Строковые литералы добавляются в 'String Literal Pool' во время загрузки класса.

3) Предотвращает ли это кэширование других строк в пуле строк?

Нет.

4) Каковы затраты производительности этого подхода по сравнению с тем, гдеЯ использую жестко закодированные строковые константы, это одно и то же (без учета стоимости доступа к полю)?Пул строк ведет себя одинаково или сильно отличается?

Это то же самое.

5) Какое среднее увеличение памяти при таком подходе, все эти строковые константы хранятся в памяти все время?

Я уже ответил.:)

Дополнительные примечания

a) Интерфейс констант - это анти-шаблон Java.Пожалуйста, избегайте этого.

b) Вы должны прочитать эту статью Javaranch .

...