2016-07-04 2 views
7

Есть хорошая причина (производительность мудрая) для замены:Является ли пример val более дорогостоящим, чем компаньонный объект val?

val SOME_CONST = "value"

с

companion object { 
    val SOME_CONST = "value" 
} 

ли добавление @JvmStatic аннотацию изменяет результат?

+0

Вы можете использовать автономный объект для констант, не обязательно компаньон;) – voddan

ответ

12

Да, a val, хранящийся в companion object, является более эффективным. Вы можете использовать Kotlin bytecode viewer, чтобы узнать, с чем скомпилированы эти параметры.

Вот вещи, которые я заметил, что может повлиять на производительность:

  • Companion объект val хранится только один раз, в отличие, например val, который фактически хранится в каждом отдельном случае, таким образом, увеличивая след экземпляры памяти (String буквального is stored in constant pool, но экземпляр будет иметь ссылку на него) и время создания экземпляра (во время построения поле должно быть заполнено).

  • Доступ к сопутствующему объекту val несколько раз подряд лучше работает с кэшем ЦП, чем с использованием val в разных экземплярах: он имеет лучшие locality of reference. Выделение разным экземплярам для доступа к val в них, скорее всего, приведет к промахам кэш-памяти CPU, что плохо для производительности.

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

  • Добавление @JvmStatic делает доступ немного быстрее. Без него доступ к значению требует получения статического Companion ссылки и вызова getSOME_CONST() на нем. С @JvmStatic будет установлен статический метод getSOME_CONST() (пропуская Companion). Также есть @JvmField, который создает публичное поле, к которому можно получить доступ напрямую, даже не называя getter.

    Но JIT-компилятор, скорее всего, оптимизирует доступ к геттеру в первых двух случаях, так что эффект аннотаций будет едва заметен.

Кроме того, помимо производительности, экземпляр val имеет семантику значения, которое может быть различным для каждого экземпляра, так companion object, кажется, соответствует случаю глобальной постоянной величины лучше.