существует ли хит производительности при использовании enum.values () по сравнению с Массивами строк?

Я использую перечисления для замены String константы в моем приложении Java (JRE 1.5).

Существует ли хит производительности, когда я рассматриваю перечисление как статический массив имен в методе, который постоянно называют (например, при рендеринге UI)?

Мой код немного походит на это:

public String getValue(int col) {
  return ColumnValues.values()[col].toString();
}

Разъяснения:

  • Я обеспокоен скрытыми затратами, связанными с перечислением values() неоднократно (например, в краске () методы).
  • Я могу теперь видеть, что все мои сценарии включают некоторых int => enum преобразование - который не является путем Java.

Какова фактическая цена извлечения values() массив? Это - даже проблема?

Разработчики Android

Ответ Read Simon Langhoff ниже, который указал ранее Фанатами На Объятиях в комментариях принятого ответа. Enum.values() должен сделать защитную копию

18
задан Nathaniel Ford 11 November 2015 в 20:14
поделиться

4 ответа

Enum.values ​​() дает вам ссылку на массив, и итерация по массиву перечислений стоит так же, как итерация по массиву струны. Между тем, сравнение значений перечисления с другими значениями перечисления может быть на быстрее , чем сравнение строк со строками.

Между тем, если вас беспокоит стоимость вызова метода values ​​() по сравнению с уже имеющейся ссылкой на массив, не беспокойтесь. Вызов методов в Java (сейчас) невероятно быстр, и каждый раз, когда это действительно имеет значение для производительности, вызов метода все равно будет встроен компилятором.

Итак, серьезно, не беспокойтесь об этом. Вместо этого сконцентрируйтесь на удобочитаемости кода и используйте Enum , чтобы компилятор уловил его, если вы когда-нибудь попытаетесь использовать постоянное значение, которое ваш код не ожидал обрабатывать.


Если вам интересно, почему сравнение enum может быть быстрее, чем сравнение строк, вот подробности:

Это зависит от того, были ли строки интернированы или нет. Для объектов Enum в системе всегда есть только один экземпляр каждого значения перечисления, поэтому каждый вызов Enum.equals () может выполняться очень быстро, как если бы вы использовали оператор == вместо метода equals () . Фактически, с объектами Enum безопасно использовать == вместо equals () , тогда как с небезопасно делать с струны.

Для строк, если строки были интернированы, то сравнение выполняется так же быстро, как и с Enum . Однако, если строки не были интернированы, тогда метод String.equals () фактически должен пройти по списку символов в обеих строках, пока не закончится одна из строк или не будет обнаружен другой символ. между двумя струнами.

Но опять же, это, вероятно, не имеет значения, даже в коде рендеринга Swing, который должен выполняться быстро. : -)


@Ben Lings указывает, что Enum.values ​​() должен выполнять защитную копию, поскольку массивы изменяемы, и вы можете заменить значение в массиве, возвращаемое ] Enum.values ​​() . Это означает, что вам нужно учитывать стоимость этой защитной копии.Однако копирование одного непрерывного массива, как правило, является быстрой операцией, если предположить, что оно реализовано «под капотом» с использованием какого-либо вызова копирования из памяти, а не наивного перебора элементов в массиве. Так что я не думаю, что это меняет окончательный ответ.

16
ответ дан 30 November 2019 в 07:23
поделиться

Как эмпирическое правило: прежде чем думать об оптимизации, догадываетесь ли вы, что этот код может замедлить работу вашего приложения?

Теперь факты.

enum - это, по большей части, синтаксический сахар, рассыпающийся в процессе компиляции. Как следствие, метод values, определенный для класса enum, возвращает статическую коллекцию (то есть загруженную при инициализации класса) с характеристиками, которые можно считать примерно эквивалентными массиву.

2
ответ дан 30 November 2019 в 07:23
поделиться

Думаю, да. И удобнее использовать константы.

-1
ответ дан 30 November 2019 в 07:23
поделиться

Если вас беспокоит производительность, измерьте.

От кода я не ожидал никаких сюрпризов, но 90% всех предположений о производительности неверны. Если вы хотите быть в безопасности, подумайте о том, чтобы переместить перечисления в вызывающий код (например, public String getValue (ColumnValues ​​value) {return value.toString ();} ).

2
ответ дан 30 November 2019 в 07:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: