I have a Sequence that I want to get the length of:
val x = (1 to 1000000)
x.length
Is this an O(1) operation? (Seems like it, from trying out a couple lines in the repl.) Why? What is a Sequence storing that makes this an O(1) operation, if it is one? (Does it just store the length of the sequence as metadata?)
(1 to 1000000) creates a Range object (not the more general Seq). Range defines length by calling count:
def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = {
// faster path for the common counting range
if (start >= 0 && end > start && end < scala.Int.MaxValue && step == 1)
(end - start) + ( if (isInclusive) 1 else 0 )
else
NumericRange.count[Long](start, end, step, isInclusive)
}
So, you can see that in the simple case given, a Range with a step size of 1, length is O(1) because it just subtracts end-start and adds one. The NumericRange.count option is more complex, but still uses mathematical operations to find the value in constant time.
As for other Seq types:
List is a linked-list and does not store length information directly, so it requires traversing the entire structure and keeping track of how many elements it sees:
def length: Int = {
var these = self
var len = 0
while (!these.isEmpty) {
len += 1
these = these.tail
}
len
}
On the other hand, something like Vector stores index information, so it can return the length in constant time:
def length = endIndex - startIndex
Other Seq types may implement length in other ways.
It depends on the implementation of Seq. Length is defined as abstract ( http://www.scala-lang.org/api/current/scala/collection/Seq.html ), so some sequences might be constant time (like arrays), some might be linear (linked lists).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With