Skip to content

Map#keySet is slow in 3.8.0-RC3 #24749

@Zschimmer

Description

@Zschimmer

Compiler version

3.8.0-RC3

Minimized code

object ScalaTest:

  private val n = 10_000

  def main(args: Array[String]): Unit =
    val map: Map[Int, Unit] = (1 to n).map(i => i -> ()).toMap

    // FAST
    meter(".toMap"):
      map.contains

    // SLOW
    val set = map.keySet
    meter(".toMap.keySet"):
      set.contains

  private def meter[A](prefix: String)(f: Int => Boolean): Unit =
    val t = System.nanoTime() / 1_000_000
    for i <- 1 to n do if !f(i) then throw new NoSuchElementException
    println(prefix + " " + (System.nanoTime() / 1_000_000 - t) + "ms")

Output

.toMap 3ms
.toMap.keySet 105ms

Expectation

Checking whether a Set derived via the Map#keySet operation contains a key should not be slower than checking whether a Map contains a key. But it's really slow.

Probably due list traversal since e55df11.

The example's execution time grows quadratically with n.

When compiled with Scalac 3.7.4, the example has same short execution times in both cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    itype:bugstat:needs triageEvery issue needs to have an "area" and "itype" label

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions