为什么Kotlin的mapOf(a到b,c到d)被认为不适合性能关键代码?

Ita*_*man 5 kotlin

Kotlin的官方"馆藏"页面包含以下内容:

在NOT性能关键代码中的地图创建可以用简单的习语来完成:mapOf(a到b,c到d).

问题:

a /这句话背后的原因是什么(我能想到的最好的解释是"a到b"表达式创建了一个额外的,瞬态的Pair对象,但我不确定).

b /以适合性能关键代码的方式初始化地图的建议最佳做法什么?

hot*_*key 12

引擎盖下有两件事可能会影响性能:

  • mapOf(...)函数需要一vararg对,并且在调用期间,为参数创建一个数组,然后传递给该函数.此操作涉及分配数组,然后使用项填充它.

  • 正如您所正确指出的那样,中缀函数会创建一对(相当于),这是另一个对象分配.a to b Pair(a, b)

紧密循环中多次执行时,分配许多对象会影响性能(包括在处理短生命对象时对垃圾收集器进行额外加载).

此外,使用数组vararg可能会影响引用的位置(而不是通过堆栈传递参数,它们被放置在位于堆中其他位置的单独内存区域中).

虽然JVM通常擅长本地优化,有时甚至可以消除分配,但这些优化并不能保证会发生.

创建地图并用项目填充的更高效的方法是:

val map: Map<Foo, Bar> = HashMap().apply { 
    put(a, b)
    put(c, d)
}
Run Code Online (Sandbox Code Playgroud)

使用apply { ... }没有引入的开销,因为它是一个内联函数. 显式类型注释Map<Foo, Bar>显示在创建映射后不改变映射的意图.