В каких случаях следует использовать Array (Buffer) и List (Buffer). Единственное отличие, которое я знаю, заключается в том, что массивы невариантны, а списки ковариантны. А как насчет производительности и некоторых других характеристик?
источник
В каких случаях следует использовать Array (Buffer) и List (Buffer). Единственное отличие, которое я знаю, заключается в том, что массивы невариантны, а списки ковариантны. А как насчет производительности и некоторых других характеристик?
Scala List
является непреложной рекурсивной структурой данных , которая является такой фундаментальной структурой в Scala, что вы должны (возможно) будете использовать его гораздо больше , чем Array
(что на самом деле изменяемый - неизменен аналог из Array
это IndexedSeq
).
Если вы работаете с Java, очевидная параллель - когда использовать LinkedList
over ArrayList
. Первый обычно используется для списков, которые только когда-либо просматриваются (и размер которых не известен заранее), тогда как последний следует использовать для списков, которые либо имеют известный размер (или максимальный размер), либо для которых важен быстрый произвольный доступ .
ListBuffer
обеспечивает преобразование с постоянным временем в a, List
что является единственной причиной для использования, ListBuffer
если требуется такое более позднее преобразование.
Scala Array
должен быть реализован на JVM с помощью массива Java, и, следовательно, он Array[Int]
может быть намного более производительным (как int[]
), чем List[Int]
(который будет упаковывать его содержимое, если вы не используете самые последние версии Scala, которые имеют новую @specialized
функцию) .
Однако я думаю, что использование Array
s в Scala должно быть сведено к минимуму, потому что кажется, что вам действительно нужно знать, что происходит под капотом, чтобы решить, действительно ли ваш массив будет поддерживаться требуемым примитивным типом или может быть упакованным как тип оболочки.
В дополнение к уже опубликованным ответам, вот некоторые особенности.
В то время как an
Array[A]
буквально представляет собой массив Java, aList[A]
- это неизменяемая структура данных, которая либоNil
(пустой список), либо состоит из пары(A, List[A])
.Различия в производительности
Array List Access the ith element θ(1) θ(i) Delete the ith element θ(n) θ(i) Insert an element at i θ(n) θ(i) Reverse θ(n) θ(n) Concatenate (length m,n) θ(n+m) θ(n) Count the elements θ(1) θ(n)
Различия в памяти
Array List Get the first i elements θ(i) θ(i) Drop the first i elements θ(n-i) θ(1) Insert an element at i θ(n) θ(i) Reverse θ(n) θ(n) Concatenate (length m,n) θ(n+m) θ(n)
Поэтому, если вам не нужен быстрый произвольный доступ, нужно подсчитывать элементы или по какой-то причине вам нужны деструктивные обновления,
List
лучше, чемArray
.источник
list = list.drop(i)
. Или, за капотом творится какая-то магия?drop
никогда не нужно копировать часть списка, которая не была удалена. Например,(x::xs).drop(1)
это точноxs
, а не "копия"xs
.Массив является изменяемым, что означает, что вы можете изменять значения каждого индекса, в то время как список (по умолчанию) является неизменным, что означает, что новый список создается каждый раз, когда вы вносите изменения. В большинстве случаев это более «функциональный» стиль работы с неизменяемыми типами данных , и вы , вероятно , следует попытаться использовать список с конструкциями , как
yield
,foreach
,match
и так далее.Что касается характеристик производительности, массив быстрее работает с произвольным доступом к элементам, тогда как список быстрее при добавлении (добавлении) новых элементов. Итерация по ним сопоставима.
источник
iterate over
из-за кеширования