Что происходит, когда мы используем цикл вместо while(true) с актерами scala?
В чем разница использования цикла вместо while(true) при использовании receive с актерами. Кажется, петля работает намного быстрее, но почему и что происходит под капотом?
Есть ли что-то плохое в использовании цикла вместо while(true)?
Подробнее о контексте. Я делаю тесты производительности в простом коде пинг / понг. И я пользуюсь приемом.
Это класс Ping:
class ReceivePing(
count : Int,
pong : Actor
) extends Actor {def act() {
var pingsLeft = count - 1
pong ! Start
pong ! ReceivePing
while(true) {
receive {
case ReceivePong =>
if (pingsLeft % 10000 == 0)
Console.println("ReceivePing: pong")
if (pingsLeft > 0) {
pong ! ReceivePing
pingsLeft -= 1
} else {
Console.println("ReceivePing: stop")
pong ! Stop
exit()
}
}
}}}
вместо while(true) он работает лучше с циклом.
Спасибо
2 ответа
С помощью loop
освобождает поток для других задач, в то время как while
не делает. Итак, если вы используете много актеров, использование loop
делает тогда более эффективным. С другой стороны, один актер, использующий while
а также receive
гораздо быстрее, чем при использовании loop
а также react
(или, в этом отношении, loop
а также receive
).
while
/receive
цикл блокирует поток, тогда как loop
/react
конструкция не Это означает, что для первой конструкции требуется один поток на каждого актера, который быстро становится медленным.
Согласно Халлеру и Одерскому 2006,
Актер, ожидающий в операторе получения, представлен не заблокированным потоком, а замыканием, которое захватывает остальные вычисления актера. Закрытие выполняется после того, как субъекту отправлено сообщение, соответствующее одному из шаблонов сообщений, указанных в получении. Выполнение замыкания является "копилкой" в потоке отправителя. Если закрытие приема прекращается, управление возвращается отправителю, как если бы процедура возвращалась. Если приемное закрытие блокируется во втором приеме, управление возвращается отправителю, вызывая специальное исключение, которое раскручивает стек вызовов получателя.
(Видимо, они позже изменили поведение receive
и переименовал старый receive
в react
.)