почтовый индекс, карта и сумма:
first.view.zip(second).map(t => t._1 - t._2).map(x => x*x).sum
- zip объединить элементы двух списков в кортеж
- view используется для ленивого вычисления списка, чтобы не строить структуру между двумя вызовами карты
(изменить, чтобы заменить reduceLeft
на sum
)
Увидев комментарии, я чувствую, что мне пришлось вернуться и рассказать о взглядах. По сути, представление превращает Traversable
в структуру, подобную итератору, поэтому не требуется создавать несколько промежуточных структур при применении таких методов, как map
, zip
и некоторых других. Члены типа GenIteratableViewLike дают представление о том, какие операции имеют специальную обработку. Поэтому, как правило, если у вас есть набор карт, фильтров, отбрасываний, takeWhile, применяемых последовательно, вы можете использовать представление для увеличения производительности. Основное правило заключается в том, чтобы применять view
рано, чтобы минимизировать количество промежуточных List
, и при необходимости использовать force
в конце, чтобы вернуться к List
(или к любой коллекции, которую вы используете). Таким образом, предложение Даниила.
Суть в производительности заключается в том, что на практике, если это важно, вам нужно выполнить проверку реальности. Вот некоторые цифры (чем ниже, тем лучше):
no view List(62, 62, 62, 62, 63) sum: 311
view before zip List(32, 31, 15, 16, 31) sum: 125
view after zip List(31, 46, 46, 31, 31) sum: 185
iterator List(16, 16, 16, 16, 15) sum: 79
zipped List(62, 47, 62, 46, 47) sum: 264
Код здесь:
import testing.Benchmark
def lots[T](n: Int, f: => T): T = if (n > 0) { f; lots(n - 1, f) } else f
def bench(n: Int, id: String)(block: => Unit) {
val times = (new testing.Benchmark {
def run() = lots(10000, block)
}).runBenchmark(n)
println(id + " " + times + " sum: " + times.sum)
}
val first = List(1, 2, 3)
val second = List(4, 5, 6)
bench(5, "no view") { first.zip(second).map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "view before zip") { first.view.zip(second).map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "view after zip") { first.zip(second).view.map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "iterator") { first.iterator.zip(second.iterator).map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "zipped") { (first, second).zipped.map((a,b) => a - b).map(x => x*x).sum }