You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中各类常量声明方式的性能差异及开销对比

Kotlin常量声明的性能开销对比(仅聚焦性能)

咱们直接直奔主题,完全不讨论可读性、最佳实践这些,只拆解你列出的四种方案在性能和资源开销上的差异:

选项1:Companion Object + const val

先看编译后的Java代码:确实会生成一个Companion内部类,并且在Thing类加载时创建一个静态的Companion实例。但重点是——访问TAG的性能和Java静态常量完全一致:

  • const val是编译期常量,TAG会被编译成Thing类的直接静态final字段,访问时直接取内存地址,根本不需要经过Companion对象。
  • 唯一的额外开销是类加载时创建一次Companion实例,这个开销微乎其微(一个空对象,占用内存极少,且只初始化一次),对运行时性能几乎没有影响。

选项2:Top-level const val

编译后生成一个ThingKt类,里面包含静态final的TAG字段:

  • 访问TAG就是直接访问静态编译期常量,和Java的static final完全一样,没有任何额外对象创建。
  • 唯一的“开销”是多了一个ThingKt类,但JVM类加载的成本极低,且这个类只包含静态常量,内存占用可以忽略。
  • 这是性能最极致的方案之一,没有多余的对象实例,访问速度最快。

选项3:External Object + const val

编译后生成的ThingConstants类有一个静态INSTANCE实例(类加载时初始化一次),同时TAG是直接的静态final字段:

  • 和选项2一样,const val TAG是编译期常量,访问时直接取静态字段,完全不需要通过INSTANCE对象。
  • 额外开销仅为类加载时创建的INSTANCE空对象,和选项1的Companion实例一样,对性能无实际影响。
  • 性能表现和选项2几乎没有差别,唯一的区别就是多了一个几乎不占资源的INSTANCE实例。

选项4:Class-level val(无const)

这个方案的性能是四种里最差的,具体细节:

  • 每个Thing实例都会持有一个TAG引用字段(虽然JVM字符串常量池会让所有实例的TAG指向同一个字符串对象,但每个实例还是会多占几个字节的引用内存)。
  • 访问TAG必须通过实例的getter方法(比如thing.getTAG()),即使JIT编译器会内联这个getter,本质上还是比直接访问静态字段多了一步操作。
  • 因为没有const修饰,TAG不是编译期常量,编译器无法在调用处直接替换成字面量,每次访问都需要通过实例获取,无法享受编译期优化。

性能总结排序(从优到劣)

  1. 选项2(顶层const) ≈ 选项3(外部object的const):性能几乎无差别,都是直接访问编译期静态常量,无多余对象开销。
  2. 选项1(companion object的const):和前两者仅差一个类加载时创建的Companion实例,对运行时性能无影响,几乎可以视为同一层级。
  3. 选项4(成员val无const):性能最差,每个实例有额外内存开销,访问速度更慢,无编译期优化。

内容的提问来源于stack exchange,提问作者jpegoraro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:49:30