Ответ
В Go len()
— это не обычная функция, а встроенная конструкция языка, которая обрабатывается компилятором особым образом. Она возвращает длину для коллекций нескольких типов.
Производительность и сложность: O(1)
Вызов len()
всегда выполняется за константное время O(1). Это возможно, потому что длина является неотъемлемой частью внутренней структуры данных и хранится в ней явно. len()
просто читает это готовое значение.
- Слайс (Slice): Структура слайса в памяти (slice header) содержит три поля: указатель на нижележащий массив, длину (
len
) и ёмкость (cap
).len(mySlice)
— это прямое чтение поляlen
.// Внутреннее представление слайса type sliceHeader struct { Data uintptr Len int Cap int }
- Строка (String): Строка, как и слайс, имеет заголовок с указателем на данные и длиной.
len(myString)
читает это поле. Важно:len()
возвращает количество байт, а не рун (символов). - Массив (Array): Длина массива является частью его типа и известна на этапе компиляции.
len(myArray)
— это, по сути, константа. - Мапа (Map): Внутренняя структура мапы содержит счётчик количества элементов.
len(myMap)
возвращает значение этого счётчика. - Канал (Channel):
len(myChan)
возвращает количество элементов, находящихся в данный момент в буфере канала.
Связь с CPU-кэшем
Прямой связи между len()
и CPU-кэшем нет. Однако, как и любая операция чтения из памяти, её скорость косвенно зависит от кэша.
Если заголовок слайса или мапы уже находится в L1/L2 кэше процессора (например, из-за того, что вы недавно работали с этой переменной), чтение поля длины будет практически мгновенным. Если данные находятся только в оперативной памяти, доступ займёт больше времени. Но даже в худшем случае это чрезвычайно быстрая операция.