是一个实例val更昂贵,然后伴侣对象VAL?

有一个很好的理由(性能明智的)来取代:

val SOME_CONST = "value"

 companion object { val SOME_CONST = "value" } 

添加@JvmStatic注解是否会改变结果?

是的, companion object存储的val更高效。 您可以使用Kotlin字节码查看器来查找这些选项编译到的内容。

以下是我注意到的可能会影响性能的事情:

  • 伴随对象val只存储一次,与实例val不同,它实际上存储在每个实例中,因此增加了实例的内存占用( String字面值存储在常量池中 ,但实例将有一个对它的引用)和实例创建时间建设,一个领域必须填写)。

  • 在不同的情况下,连续访问伴随对象val多次使用CPU缓存比使用val更好:它具有更好的引用位置 。 解引用不同的实例来访问它们中的val可能会导致CPU缓存未命中,这对性能不利。

    但是,如果val仅用于同一类的实例方法中,则所描述的效果几乎不会影响性能,因为方法可能会解决this ,甚至可能会更好,在访问伴随对象时不会导致可能的缓存未命中。

  • 添加@JvmStatic使访问速度更快。 没有它,访问该值需要获取静态Companion引用并调用getSOME_CONST() 。 使用@JvmStatic ,将会有静态方法getSOME_CONST() (跳过Companion )。 还有@JvmField ,它可以直接访问公共字段,而无需调用getter。

    但JIT编译器可能会优化前两种情况下的getter访问,所以注释的效果几乎不会引起注意。

此外,除了性能,实例val具有一个值的语义,每个实例的值可能不同,所以companion object似乎更好地适应全局常量的情况。