повышение производительности с помощью FlatMap против For-понимания - PullRequest
0 голосов
/ 09 марта 2020

У меня есть актер в моем игровом приложении, и каждый тик (2 se c) отправляет сообщение некоторому методу:

onSomething() : Future[Unit] = {
    for {
        a <- somethingThatReturnsFuture
        b <- anotherThingThatReturnsFuture
    }
}

Этот метод имеет два вызова, которые возвращают будущее, поэтому я решил использовать для понимания, но правда ли, что для понимания блокирует? Таким образом, akka не может вызвать этот метод снова даже с 16 экземплярами, которые они запускают, пока метод не завершится?

Если у меня будет метод для работы с flatMap / map, это позволит Акке иметь лучшую производительность? Как это:

onSomething() : Future[Unit] = {
    somethingThatReturnsFuture.flatMap(res1 => {
        anotherThingThatReturnsFuture.map(res2 => {
            //whatever
        })
    })
}

спасибо

Ответы [ 2 ]

4 голосов
/ 09 марта 2020

Согласно комментарию Луиса, for-понимания - это просто syntacti c sugar

"Scala" для пониманий "syntacti c sugar для составления нескольких операций с foreach, map, flatMap, filter или withFilter. Scala фактически переводит for-expression в вызовы этих методов, так что любой класс, предоставляющий их, или их подмножество, может использоваться для понимания.

, который расширяется до базовой монады c операций, таким образом, не должно быть никакого снижения производительности при непосредственном использовании операций monadi c. Если ваши методы не зависят друг от друга, то вы можете получить одинаковую производительность, воспользовавшись преимуществом Future s, являющимся рвением , и запустить их вне пределов понимания, как, например,

val aF = somethingThatReturnsFuture()
val bF = anotherThingThatReturnsFuture() // I started without waiting on anyone 

for {
  a <- aF
  b <- bF
} yield { 
  a + b
}

Однако если вычисление b зависит от a, то вы не сможете запустить их параллельно

for {
  a <- somethingThatReturnsFuture
  b <- anotherThingThatReturnsFuture(a)
} yield { 
  a + b
}

Здесь anotherThingThatReturnsFuture "блоки" в смысле необходимости ждать somethingThatReturnsFuture .

0 голосов
/ 09 марта 2020

Прежде всего. Поскольку методы, которые вы вызываете, возвращают Future, ни один из них не заблокирует выполнение Thread.

Но это правда, что flatmap будет последовательно объединять две операции. Я имею в виду, что он вызовет первый метод, затем сразу вернется, потому что это Future, а затем вызовет второй.

Это произойдет в двух опциях, которые вы опубликовали ранее (для понимания и flatmap), потому что они в основном одинаковы.

Если вы хотите вызывать два метода одновременно (в двух разных потоках), так что вы не знаете, какой из них начнет выполняться первым, Вы должны использовать параллельные коллекции.

Но в вашем случае, возможно, лучше не использовать их, потому что использование фьючерсов гарантирует, что поток не будет блокировать

...