Гость
Форумы / Java [игнор отключен] [закрыт для гостей] / scala задачка на мап флатмап / 25 сообщений из 31, страница 1 из 2
09.06.2019, 16:19
    #39824625
andreykaT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
собссно есть структура Future[Set[Future[Int]] надо из нее сделать Future[Set[Int]]

у меня уже мозг плавится как их там разложить.
...
Рейтинг: 0 / 0
09.06.2019, 17:06
    #39824631
andreykaT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
вопрос снят:

автор in.foldLeft(successful(cbf(in))) {
(fr, fa) => fr.zipWith(fa)(_ += _)
}.map(_.result())(InternalCallbackExecutor)
...
Рейтинг: 0 / 0
09.06.2019, 21:22
    #39824662
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
andreykaTсобссно есть структура Future[Set[Future[Int]]
Ну это какой-то треш, кратко говоря проблема в том что кто-то довел до такой обертки. Set[Future[Int]] элементарно переводится в Future[Set[Int]] через метод sequence. Соответственно там у тебя есть метод который оборачивает все в ещё один Future - лучше проапдейтить метод, чтобы доп обёртка просто не создавалась, ну а если нельзя - то просто вызываем flatten и дело в шляпе.

Код решения, даже мне с ФП головного мозга кажется клочком, после которого хочется окунуться назад в java. Теперь я понимаю почему тебе скала так тяжело заходит, с таким то Легаси кодом
...
Рейтинг: 0 / 0
09.06.2019, 21:43
    #39824667
andreykaT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
поздравляю тебя. это исходник того метода, который ты мне только что посоветовал.

я тоже с тобой согласен что исходники скальных утильных либ - это лютый пиндец. в основном. но это не точно.
...
Рейтинг: 0 / 0
09.06.2019, 21:48
    #39824669
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
А какой прикладной смысл в вложенных фьючерсах? Хотелось-бы пример из реальной жизни.
...
Рейтинг: 0 / 0
09.06.2019, 21:49
    #39824671
andreykaT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
забыл никandreykaTсобссно есть структура Future[Set[Future[Int]]
Ну это какой-то треш, кратко говоря проблема в том что кто-то довел до такой обертки. Set[Future[Int]] элементарно переводится в Future[Set[Int]] через метод sequence. Соответственно там у тебя есть метод который оборачивает все в ещё один Future - лучше проапдейтить метод, чтобы доп обёртка просто не создавалась, ну а если нельзя - то просто вызываем flatten и дело в шляпе.

Код решения, даже мне с ФП головного мозга кажется клочком, после которого хочется окунуться назад в java. Теперь я понимаю почему тебе скала так тяжело заходит, с таким то Легаси кодом
как такая матрёшка вышла ответ очень простой -
мы ходим в базу за данными, прилетает футура.

с данными из базы мы идем на сервис через веб, с которого снова прилетает футура
с полученными данными с сервиса мне надо еще раз сходить в базу и проапдейтить данные - и здесь прилетает футура.

согласись, что набор действий более чем банальный. я бы мог флатмапом всё разложить. но в третьем шаге надо обходить полученный список последовательно и там и вылетает сет футур.
...
Рейтинг: 0 / 0
09.06.2019, 21:52
    #39824672
andreykaT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
maytonА какой прикладной смысл в вложенных фьючерсах? Хотелось-бы пример из реальной жизни.
это просто дань моде. а так есть мнение что экзекутор "типа" более правильно всё разложит-распараллелит там где можно и выйдет "типа" оптимальнее. сам лично не проверял. в книжках такое мнение читал. верю написанному.
...
Рейтинг: 0 / 0
09.06.2019, 23:00
    #39824683
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
Структурно - похоже на RecursiveAction/ForkJoin
...
Рейтинг: 0 / 0
09.06.2019, 23:45
    #39824700
andreykaT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
Да форкджойн. Но там ты руками все делаешь. А тут типа оно само тебя заставляет)) матрехи писать да раскладывать на монады-функторы.
Кстати, форкджойн имхо не взлетел.
...
Рейтинг: 0 / 0
10.06.2019, 22:55
    #39825132
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
Вообще Future не самый лучший инструмент в Scala и ФП. Предпочтительнее юзать monix.Task либо IO из Cats\ScalaZ. Основной косяк Future - что он начинает исполнение сразу после создания и девелопер никак не контролирует это, что приводит к потере referrential transparency. Но это лирика.

Если я правильно понял задачу, то не вижу в ней ничего сложного, если хочешь можешь добавить недостаюшие детали а я потом попробую привести решение. Итак

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration

object Test extends App{

  type OrderId = Int
  type ItemId = Int
  case class Order(OrderId:Int, items:Set[ItemId])
  case class Item(id:ItemId)

  def lookupOrder(id:OrderId):Future[OrderId] = {
    println(s"Retrieving order $id")
    Thread.sleep(500)
    println(s"Order retrieved")
    Future(id)
  }
  def fetchOrder(id:OrderId):Future[Order] = {
    println(s"Fetching order $id")
    Thread.sleep(500)
    println(s"Order fetched")
    Future(Order(id, Set(1,2,3,4,5)))
  }

  def fetchItem(id:ItemId) : Future[Item] = {
    println(s"Fetching item $id")
    Thread.sleep(5000)
    println(s"item fetched")
    Future(Item(id))
  }

  def program(id:OrderId) = {
    val future: Future[Set[Item]] = for {
      orderId <- lookupOrder(id)
      order <- fetchOrder(orderId)
      items <- Future.sequence(order.items.par.map(fetchItem).seq)
    } yield items
    val result = Await.result(future, Duration.Inf)
    println(s"Fetched items ${result.mkString(",")}. Done!")
  }

  program(1)
}


В общем-то все тривиально
...
Рейтинг: 0 / 0
10.06.2019, 22:58
    #39825134
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
lookupOrder - берем данные из базы
fetchOrder - идем на рест и ретривим айтемы
fetchItem - берем из базы детали по каждому айтему

Все правильно ведь?
...
Рейтинг: 0 / 0
10.06.2019, 23:48
    #39825137
andreykaT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
так да. я в итоге так и сделал. через фьюча-сиквенз.
и в общем то код по строкам вышел в несколько строк как по-сути и у тебя.

без фьюча-сиквенз разложить эти монады-функторы у тебя так же лаконично без вырвиглазного набора символов увы не выйдет.

ну или мне мозгов не хватило как.

насчет скалаз и пр ну это совсем уже функционализм головного мозга. скала всё же не чистый ФП это мультипарадигма ООП и рюшки ФП я считаю, вполне (на мой взгляд) сбалансировано.
...
Рейтинг: 0 / 0
10.06.2019, 23:49
    #39825139
andreykaT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
...ну разве что я сделал на флатмап-мапах а не на форкомпрехеншене как ты. впрочем, это одно и то же.
...
Рейтинг: 0 / 0
11.06.2019, 00:49
    #39825144
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
maytonСтруктурно - похоже на RecursiveAction/ForkJoin

На самом деле вообще ничего похожего. Тут Струтктура такая - колл 1-> колл 2 зависящий от колл 1 -> N коллов зависящих от колл2(но не зависящих друг от друга).

Банальный тредпул. В форкджойне вся соль в том что там рекурсивные таски, которые сплитятся на более мелкие, и одни из них зависят от других
...
Рейтинг: 0 / 0
11.06.2019, 00:57
    #39825146
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
andreykaT
без фьюча-сиквенз разложить эти монады-функторы у тебя так же лаконично без вырвиглазного набора символов увы не выйдет.


Ну так для этого sequence и придумали. На самом деле все глубже, это один из ФП паттернов, но в отличие от ООП паттернов, он заимплментирован в коде, причем раз и навсегда, в отличие от... списка печатных инструкций ООП:)

sequence он гораздомасштабнее, его надо применять когда у тебя структура данных имеет тип F[G[A]] а тебе надо поменять на G[F[A]], например это может быть List[Option[Int]] -> Option[List[Int]] или List[Future[Int]] -> Future[List[Int]].

List в данном случае представляет собой абстракцию Traversable(но это может быть и другие типы данных, в том числе твой Order), у которой есть метод sequence, и ему до лампочки какой вложенный тип - Future,Either,Option и т.д. Он просто выворачивает структуру наизнанку, вот она красота ФП во всей ее мощи. То что код смотрится ужасным с точки зрения имплементации sequence - ну что ж, это цена за супер-абстракцию, недостижимую для ООП. Собственно вся сложность в изучении ФП сводится к изучению такого рода паттернов, и да это требьует времени, но рано или поздно даже такой синтаксис становится читаемым
...
Рейтинг: 0 / 0
11.06.2019, 01:05
    #39825149
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
забыл никБанальный тредпул. В форкджойне вся соль в том что там рекурсивные таски, которые сплитятся на более мелкие, и одни из них зависят от других
Нет. В случае использования RecursiveAction ничего ни от кого не зависит.
А соль в том что диспетчеризация очень простая. Пул загружен на 100% эффективно.
...
Рейтинг: 0 / 0
11.06.2019, 01:11
    #39825150
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
andreykaTДа форкджойн. Но там ты руками все делаешь. А тут типа оно само тебя заставляет)) матрехи писать да раскладывать на монады-функторы.
Кстати, форкджойн имхо не взлетел.
Беда в том что у нас с вами нет объективного теста который бы показал что там перформит лучше.
Пока я просто вижу игры разума. Ну написал так. Потом эдак. Потом еще 100500 способов как решить
задачу. Вплоть до brainfuck.

А что зайдет в продуктив? Вот мой вопрос.
...
Рейтинг: 0 / 0
11.06.2019, 01:47
    #39825153
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
maytonНет. В случае использования RecursiveAction ничего ни от кого не зависит.
Ну как это не зависит? Если RecursiveAction создает подтаски, то она заканчивается только когда сабтаски закончили исполнение. В случае тредпула этот экшен висел бы и занимал отдельную нить, в случае форкджойна такого не будет, собственно он для этого и был создан.
maytonА соль в том что диспетчеризация очень простая. Пул загружен на 100% эффективно.
Не понял при чем здесь диспетчеризация. А насчет загруженности - очень легко можно написать код который будет создавать тысячу RecursiveAction но каждый этот таск будет зависеть от всех остальных, так что по итогу все будет выполняться фактичски последовательно. Например у нас есть лист из 1000 элементов и мы создаем экшен в котором суммируем элемент и некую функцию от всех остальных элементов.
Если ты про work steal - то да, это делает пул более эффективным, но это никаким образом не относится к задаче ТС
...
Рейтинг: 0 / 0
11.06.2019, 02:01
    #39825154
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
maytonБеда в том что у нас с вами нет объективного теста который бы показал что там перформит лучше.
Пока я просто вижу игры разума. Ну написал так. Потом эдак. Потом еще 100500 способов как решить
задачу. Вплоть до brainfuck.

А что зайдет в продуктив? Вот мой вопрос.
Не всегда определящим фактором является перфоманс. Иногда безопасность, тестируемость, расширяемость на порядок важнее. В случае форк-джойна ты намертво привязан к нему, ко всей этой инфраструктуре, у твоего заказчика не было задачи - разбить лист на recursiveAction и сджойнить их рлдучив тем самым сумму. Скорее задача - просто посчитать сумму, и в случае ФП, вот этот вот энвайрнмент можно абстрагировать в типе программы и сделать ортогональным.

Поясню на примере, задачу ТС можно было написать так -
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration

object Test extends App{

  type OrderId = Int
  type ItemId = Int
  case class Order(OrderId:Int, items:Set[ItemId])
  case class Item(id:ItemId)

  def lookupOrder(id:OrderId):M[OrderId] = {
    M.unit(id)
  }
  def fetchOrder(id:OrderId):M[Order] = {
    M.unit(Order(id, Set(1,2,3,4,5)))
  }

  def fetchItem(id:ItemId) : M[Item] = {
    M.unit(Item(id))
  }

  def program(id:OrderId, m:M:Monad) = {
    val definitionOfProgram: M[Set[Item]] = for {
      orderId <- lookupOrder(id)
      order <- fetchOrder(orderId)
      items <- m.sequence(order.items.par.map(fetchItem).seq)
    } yield items
    val result = m.run(definitionOfProgram)
    println(s"Fetched items ${result.mkString(",")}. Done!")
  }

  program(1, Future) -- для продакшена
  program(1, Id) -- для тестов

}
 
trait Monad{
  unit() - поместить в контекст
  flatMap - вычислить следущий компутейшен в цепочке
  run - выйти из контекста
}

Id extends Monad {
   unit == noop
   flatMap == просто вызов следующего по цепочке
   run == вернуть значение
}



Таким образом, можно всего лишь одной(!) строкой поменять исполнение программы из многопоточного в однопоточный(для тестов)
...
Рейтинг: 0 / 0
11.06.2019, 08:41
    #39825189
andreykaT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
Чет я не понял где эта важная одна строка?
...
Рейтинг: 0 / 0
11.06.2019, 08:50
    #39825193
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
program(1, Future) -- для продакшена
program(1, Id) -- для тестов
...
Рейтинг: 0 / 0
11.06.2019, 08:51
    #39825194
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
Есественно это псевдокод, чтобы не загружать scala деталями. Но итог тот же. Финальный вызов будет program[Monad](params)
...
Рейтинг: 0 / 0
11.06.2019, 11:09
    #39825240
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
забыл никНе всегда определящим фактором является перфоманс. Иногда безопасность, тестируемость, расширяемость на порядок важнее. В случае форк-джойна ты намертво привязан к нему, ко всей этой инфраструктуре, у твоего заказчика не было задачи - разбить лист на recursiveAction и сджойнить их рлдучив тем самым сумму. Скорее задача - просто посчитать сумму, и в случае ФП, вот этот вот энвайрнмент можно абстрагировать в типе программы и сделать ортогональным.

Не согласен. В случае форк-джойна во главу угла ставится перформанс. Остальные фичи не имеют значения.
Но обсуждая форк мы уклонились от задачи автора. У него задача была сделать Future[Set[Int]] из чего-то там.

Другие критерии - неизвестны. Поэтому тут любой способ хорош.
...
Рейтинг: 0 / 0
11.06.2019, 11:20
    #39825247
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
maytonзабыл никНе всегда определящим фактором является перфоманс. Иногда безопасность, тестируемость, расширяемость на порядок важнее. В случае форк-джойна ты намертво привязан к нему, ко всей этой инфраструктуре, у твоего заказчика не было задачи - разбить лист на recursiveAction и сджойнить их рлдучив тем самым сумму. Скорее задача - просто посчитать сумму, и в случае ФП, вот этот вот энвайрнмент можно абстрагировать в типе программы и сделать ортогональным.

Не согласен. В случае форк-джойна во главу угла ставится перформанс. Остальные фичи не имеют значения.
Но обсуждая форк мы уклонились от задачи автора. У него задача была сделать Future[Set[Int]] из чего-то там.

Другие критерии - неизвестны. Поэтому тут любой способ хорош.
Автор java concurrency in practice and jvm architect - Brian Goetz describes the situation best: https://www.ibm.com/developerworks/library/j-jtp11137/index.html

Using conventional thread pools to implement fork-join is also challenging because fork-join tasks spend much of their lives waiting for other tasks. This behavior is a recipe for thread starvation deadlock, unless the parameters are carefully chosen to bound the number of tasks created or the pool itself is unbounded. Conventional thread pools are designed for tasks that are independent of each other and are also designed with potentially blocking, coarse-grained tasks in mind — fork-join solutions produce neither.



Work stealing немного ускоряет обработку но это лишь бонус. Вообще почитай тред - https://stackoverflow.com/questions/21156599/javas-fork-join-vs-executorservice-when-to-use-which
Там много интересного
...
Рейтинг: 0 / 0
11.06.2019, 11:33
    #39825253
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
scala задачка на мап флатмап
Спасибо. Почитаем
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / scala задачка на мап флатмап / 25 сообщений из 31, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]