Search code examples
scalaperformancecollectionssequencescala-3

In Scala 3 is `isEmpty` on a sequence faster than `length == 0`?


In Scala 3 I have a sequence defined, for example:

val seq = List(1,8,9)

Is the operation seq.isEmpty faster than seq.length == 0?

Thinking about it, `isEmpty should be faster (because it only has to check whether a first "next" element does not exist), but is it in Scala 3 really implemented like this?


Solution

  • Scala 3 still uses Scala 2.13 standard library.

    On a List, the 2 operations are defined as follow:

    // https://github.com/scala/scala/blob/951cc9b1cc3dccd36762de4d6176bf8fd76a842f/src/library/scala/collection/immutable/List.scala#L142
    
    override final def isEmpty: Boolean = this eq Nil
    
    // https://github.com/scala/scala/blob/951cc9b1cc3dccd36762de4d6176bf8fd76a842f/src/library/scala/collection/immutable/List.scala#L361
    
    override final def length: Int = {
      var these = this
      var len = 0
      while (!these.isEmpty) {
        len += 1
        these = these.tail
      }
      len
    }
    

    It's thus expected that isEmpty is way faster than length for Lists.

    Other collections types may have different implementations.

    Note that in general you should always run some benchmarks (with JMH for instance) if you want to compare two implementations. The theorical cost and the actual time spent can be significantly different for many reasons including JVM optimizations.