Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a instance val more costly then companion object val?

Tags:

kotlin

Is there a good reason (performance-wise) to replace a:

val SOME_CONST = "value"

with

companion object {
    val SOME_CONST = "value"
}

Does adding a @JvmStatic annotation changes the outcome?

like image 695
atok Avatar asked Jul 04 '16 06:07

atok


1 Answers

Yes, a val stored in companion object is more efficient. You can use Kotlin bytecode viewer to find out what these options are compiled to.

Here are the things I noticed that might affect performance:

  • Companion object val is stored only once, unlike instance val, which is actually stored in each instance thus increasing the instances memory footprint (String literal is stored in constant pool, but an instance will have a reference to it) and instance creation time (during the construction, a field must be filled in).

  • Accessing companion object val several times in a row works better with CPU cache than using val in different instances: it has better locality of reference. Dereferencing different instances to access the val in them will likely lead to CPU cache misses, which is not good for performance.

    However, if the val is only used inside instance methods of the same class, the described effect will scarcely affect performance because the methods will likely dereference this anyway, and this may even work better, not causing probable cache miss while accessing the companion object.

  • Adding @JvmStatic makes the access a bit faster. Without it, accessing the value requires getting static Companion reference and calling getSOME_CONST() on it. With @JvmStatic, there will be static method getSOME_CONST() (skipping Companion). There's also @JvmField that makes a public field that can be accessed directly without even calling getter.

    But JIT compiler will likely optimize the getter access of the first two cases, so that the effect of the annotations will be barely noticeable.

Also, apart from performance, instance val has semantics of a value that might be different for each instance, so companion object seems to fit the case of global constant value better.

like image 177
hotkey Avatar answered Sep 27 '22 17:09

hotkey