2013-08-28 2 views
1

Из того, что я прочитал, следует предпочесть использовать общий Seq при определении последовательностей вместо конкретных реализаций, таких как List или Vector.Преобразование между различными реализациями Seq в Scala

Хотя у меня есть части моего кода, когда последовательность будет использоваться в основном для полного обхода (сопоставление, фильтрация и т. Д.) И некоторых частей моего кода, где одна и та же последовательность будет использоваться для операций индексирования (indexOf, lastIndexWhere).

В первом случае, я считаю, что лучше использовать LinearSeq (implem является List), тогда как во втором случае это лучше использовать IndexedSeq (implem является Vector).

Мой вопрос: нужно ли я в явном виде перевести метод toList и toIndexedSeq в мой код или сделать преобразование под капотом разумным образом? Если я использую эти преобразования, это штраф за производительность при переходе между IndexedSeq и LinearSeq?

Заранее спасибо

ответ

1

Vector почти всегда вне выполнения List. Если ваш алгоритм не использует только ::, head и tail, Vector будет быстрее, чем List. Использование List - это скорее концептуальный вопрос по вашему алгоритму (данные структурированы в стеке, только доступ к голове/хвосту, добавление элементов только путем добавления, использование сопоставления шаблонов (которое может использоваться с Vector, просто для меня более естественно используйте его с List)).

Вы можете посмотреть на Why should I use vector in scala

Теперь для некоторых хороший номер для сравнения (явно не в 'реальный' тест, но а):

val l = List.range(1,1000000) 
val a = Vector.range(1,1000000) 

import System.{currentTimeMillis=> milli} 

val startList = milli 
l.map(_*2).map(_+2).filter(_%2 == 0) 
println(s"time for list map/filter operations : ${milli - startList}") 

val startVector = milli 
a.map(_*2).map(_+2).filter(_%2 == 0) 
println(s"time for vector map/filter operations : ${milli - startVector}") 

Выход:

time for list map/filter operations : 1214 
time for vector map/filter operations : 364 

Редактировать: Просто понял, что это на самом деле не отвечает на ваш вопрос. Насколько мне известно, вам придется самому позвонить вList/toVector. Что касается выступлений, это зависит от вашей последовательности, но, если вы не собираетесь туда и обратно все время, это не должно быть проблемой.

Еще раз, не является серьезным ориентиром, но:

val startConvToList = milli 
a.toList 
println(s"time for conversion to List: ${milli - startConvToList}") 

val startConvToVector = milli 
l.toVector 
println(s"time for conversion to Vector: ${milli - startConvToVector}") 

Выход:

time for conversion to List: 48 
time for conversion to Vector: 18 
+0

Спасибо очень ясно !! –

+0

Эти тесты не очень надежны, чтобы пройти. Нетрудно найти случаи, когда «Список» превосходит «Вектор». Например, если они уже являются объектами (без бокса), а коллекция - только, например. 22 long, 'List' выигрывает на карте примерно на 20%. 'List' создает больше мусора; в зависимости от влияния GC, он может быть почти бесплатным или довольно дорогостоящим. –

0

Я сделал то же самое для IndexOf и Vector также более производительным

val l = List.range(1,1000000) 
val a = Vector.range(1,1000000) 

import System.{currentTimeMillis=> milli} 

val startList = milli 
l.indexOf(500000) 
println("time for list index operation : " + (milli - startList)) 

val startVector = milli 
a.indexOf(500000) 
println("time for vector index operation : " + (milli - startVector)) 

Выход:

time for list index operation : 36 
time for vector index operation : 33 

Так что я думаю, я должен использовать Vector все времена во внутренних реализациях, но я должен использовать Seq, когда я построю интерфейс, как указано здесь: Difference between a Seq and a List in Scala

Смежные вопросы