#scala #elementwise-operations
#scala #поэлементные операции
Вопрос:
Используя два списка, поэлементное умножение этих списков и сумму результирующего списка можно вычислить следующим образом.
(List1 , List2).zipped.foldLeft(0.0) { case (a, (b, c)) => a b * c }
Как я могу выполнить эту операцию для двух итераторов в Scala оптимальным и быстрым способом?
Комментарии:
1. Извините, я не понимаю, в чем вопрос.
2. Напишите тест, иначе это просто предположение. Итераторы могут быть быстрыми, потому что они могут проходить структуру, не вычисляя вещи дважды, но я бы избегал любых заявлений об оптимальности этого или любого другого решения. Ваш текущий может быть близок к «оптимальному» или, по крайней мере, достаточно быстр.
3. Я тоже немного смущен. Помимо части производительности, оба
zip
иfold
присутствуют в итераторах. Не уверен, что вас смутило в итераторах. Код будет выглядеть почти идентично. Вы реализовали это и не были удовлетворены его производительностью?4. какое улучшение производительности вы ищете для памяти (этот список слишком большой) или временной сложности? ваша текущая реализация выглядит достаточно хорошо.
5. @sinanspd Я использовал код aboove и предоставил итератор вместо списка. Но этот код не работает
Ответ №1:
(iterator1 zip iterator2).foldLeft(0.0) { case (a, (b, c)) => a b * c }
я полагаю, все в порядке. Если вы хотите выжать из него последнюю каплю производительности, используйте массивы и цикл while.
Ответ №2:
Вы можете использовать этот фрагмент кода, который должен работать с любой коллекцией и любым числовым типом.
Он пытается быть эффективным, делая все за один обход. Однако, как сказал @Martijn, если вам нужно, чтобы это было наиболее эффективным решением, тогда просто используйте простые массивы примитивного типа, такие как Int или Double и a while
.
def dotProduct[N : Numeric](l1: IterableOnce[N], l2: IterableOnce[N]): N =
l1.iterator.zip(l2).map {
case (x, y) => Numeric[N].times(x, y)
}.sum
(примечание: этот код предназначен для 2.13
, для 2.12-
вы можете использовать Iterable вместо IterableOnce)