5

Kotlin's official "collections" page contains the following remark:

Map creation in NOT performance-critical code can be accomplished with simple idiom: mapOf(a to b, c to d).

Questions:

a/ What is the reason behind this remark (the best explanation I could come up with is that the "a to b" expressions create an extra, transient, Pair object, but I am not sure).

b/ What is the suggested best practice for initializing a map in a way that is suitable for performance-critical code?

Itay Maman
  • 30,277
  • 10
  • 88
  • 118

1 Answers1

14

There are two things that happen under the hood that might affect performance:

  • The mapOf(...) function expects a vararg of pairs, and, during a call, an array is created for the arguments and then passed to the function. This operation involves allocating an array and then filling it with the items.

  • As you correctly noted, the a to b infix function creates a pair (equivalent to Pair(a, b)), which is another object allocation.

Allocating many objects affects performance when done many times in tight loops (including additional load on garbage collector, when dealing with short-living objects).

Additionally, using an array for the vararg may affect locality of reference (instead of passing the arguments through the stack, they are placed into a separate memory region located somewhere else in the heap).

While JVMs are usually good at local optimizations and can sometimes even eliminate allocations, these optimizations are not guaranteed to happen.

A more performant way to create a map and fill it with items is:

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

Using apply { ... } introduces no overhead since it is an inline function. An explicit type annotation Map<Foo, Bar> shows the intention not to mutate the map after it is created.

hotkey
  • 140,743
  • 39
  • 371
  • 326
  • You can also use the assignment approach. Not much difference in this case, but could code in the apply with `this[a] = b`. I prefer the myMap[a] = b, but obviously it's preference. – Mikezx6r Feb 11 '18 at 02:46