Должен ли я кэшировать систему.метод getproperty("линии.разделитель")?
рассмотрим такой метод:
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
for (final Room room : map)
{
sb.append(room.toString());
sb.append(System.getProperty("line.separator")); // THIS IS IMPORTANT
}
return sb.toString();
}
System.getProperty("line.separator")
можно вызывать много раз.
должен ли я кэшировать это значение с public final static String lineSeperator = System.getProperty("line.separator")
а позже использовать только lineSeperator
?
или System.getProperty("line.separator")
так же быстро, как с помощью статического поля?
5 ответов
Я вижу, что ваш вопрос представляет собой ложную дихотомию. Я бы ни за что не позвонил getProperty
каждый раз, ни объявить статическое поле для него. Я бы просто извлек его в локальную переменную в toString
.
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
final String newline = System.getProperty("line.separator");
for (final Room room : map) sb.append(room.toString()).append(newline);
return sb.toString();
}
кстати, я сравнил вызов. Код:
public class GetProperty
{
static char[] ary = new char[1];
@GenerateMicroBenchmark public void everyTime() {
for (int i = 0; i < 100_000; i++) ary[0] = System.getProperty("line.separator").charAt(0);
}
@GenerateMicroBenchmark public void cache() {
final char c = System.getProperty("line.separator").charAt(0);
for (int i = 0; i < 100_000; i++) ary[0] = (char)(c | ary[0]);
}
}
результаты:
Benchmark Mode Thr Cnt Sec Mean Mean error Units
GetProperty.cache thrpt 1 3 5 10.318 0.223 ops/msec
GetProperty.everyTime thrpt 1 3 5 0.055 0.000 ops/msec
кэшированные подход более чем на два порядка быстрее.
обратите внимание, что общее воздействие getProperty
вызов против всего, что строковое здание очень, очень маловероятно, что это будет заметно.
вам не нужно бояться, что разделитель строк изменится во время работы вашего кода, поэтому я не вижу причин против его кэширования.
кэширование значения, безусловно, быстрее, чем выполнение вызова снова и снова, но разница, вероятно, будет незначительной.
Так как это так легко сделать, почему нет? по крайней мере реализация System.getProperty()
придется сделать поиск хэш-таблицы (даже если кэшируется внутри), чтобы найти запрашиваемое свойство, а затем виртуальный метод getString()
будет вызываться для результирующего объекта. Ни один из них не очень дорогим, но должен быть вызван несколько раз. Не говоря уже о многих String
временные будут созданы и нуждаются в GCing после.
Если вы переместите это на вершину ваш цикл и повторное использование одного и того же значения, вы избегаете всех этих проблем. Так почему бы и нет?
если вы узнали о проблеме производительности, которая, как вы знаете, относится к этому, да.
если у вас нет, то нет, поиск вряд ли будет иметь достаточно накладных расходов, чтобы иметь значение.
это подпадает под одну или обе общие категории "микро-оптимизация" и "преждевременная оптимизация".":-)
но если вы беспокоитесь об эффективности, вы, вероятно, есть много больше возможностей в ваш toString
метод регенерация строки каждый раз. Если toString
будет вызываться много, а не кэшировать Терминатор строки, кэшировать сгенерированную строку и ясно, что всякий раз, когда ваша карта комнат меняется. Например:
@Override
public String toString()
{
if (cachedString == null)
{
final StringBuilder sb = new StringBuilder();
final String ls = System.getProperty("line.separator");
for (final Room room : map)
{
sb.append(room.toString());
sb.append(ls);
}
cachedString = sb.toString();
}
return cachedString;
}
...и когда ваша карта изменится, сделайте
cachedString = null;
это много больше взрыва для доллара (доллар является накладными расходами дополнительного поля). Предоставлено это на экземпляр, а не на класс, поэтому (ссылка на более ранний комментарий об эффективности) только сделайте это, если у тебя есть на то веская причина.
Если системное свойство гарантированно останется постоянным во время приложения, его можно кэшировать, но в целом вы потеряете функцию свойства, которая изменяет поведение при его изменении.
например, генератор текста может использовать свойство для генерации текста для windows или linux и позволяет динамически изменять свойство в приложении, почему бы и нет ?
В общем случае улавливание свойства подразумевает бесполезность функции методов-setproperty.