(1 to 1000000)
создает объект Range
(не более общий Seq
). Range
определяет length
, вызывая 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)
}
Итак, вы можете видеть, что в данном простом случае Range
с размером шага 1, length
- это O (1), потому что он просто вычитает end-start
и добавляет единицу. Параметр NumericRange.count
является более сложным, но все еще использует математические операции для поиска значения в постоянное время.
Что касается других Seq
типов:
List
является связанным списком и не хранит информацию о длине напрямую, поэтому он требует прохождения всей структуры и отслеживания того, сколько элементов он видит:
def length: Int = {
var these = self
var len = 0
while (!these.isEmpty) {
len += 1
these = these.tail
}
len
}
С другой стороны, что-то вроде Vector
хранит информацию индекса, поэтому он может возвращать длину в постоянное время:
def length = endIndex - startIndex
Другие Seq
типы могут реализовывать length
другими способами.