Как построение вычислений для больших задач сравнивается с одновременным выполнением нескольких шагов? - PullRequest
0 голосов
/ 04 октября 2018

У меня есть следующие две части кода, написанные на Scala / Monix:

def f1(input) =
  for {
    a <- task1(input)
    b <- task2(a)
    c <- task3(b)
  } yield (c).runSyncUnsafe

и

def f2(input) = {
  val a = task1(input).runSyncUnsafe
  val b = task2(a).runSyncUnsafe
  task3(b).runSyncUnsafe
}

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

Я знаю, что должен написать тест для сравнения двух реализаций, но для этого потребуется многорефакторинг устаревшего кода.Кроме того, профилирование двух версий не так просто в нашей конкретной ситуации, поэтому я сначала спрашиваю здесь, в надежде получить ответ от кого-то, кто имеет большой опыт работы с Scala / Monix:

Как эти две вещи должны сравниваться с точки зренияпроизводительности под большой нагрузкой?Это реальная проблема или не проблема?

1 Ответ

0 голосов
/ 04 октября 2018

Как правило, лучше оставаться асинхронным как можно дольше.Таким образом, вы могли бы написать f1 следующим образом:

def f1(input) =
  for {
    a <- task1(input)
    b <- task2(a)
    c <- task3(b)
  } yield c

Затем вызывающий абонент может решить, будет ли он вызывать runSyncUnsafe или асинхронный вызов (runAsync, runOnComplete) или flatMap с другимзадача.Это удаляет вызов Unsafe из вашего кода и предоставляет вызывающей стороне возможность решить, быть ли безопасным или нет.

Что касается производительности, то задачи будут оцениваться последовательно в любом случае, поскольку последующие задачи зависят отрезультаты предыдущих заданий.

...