Каковы некоторые возможности улучшают производительность / параллелизм в следующей Scala + Akka Code?

StackOverflow https://stackoverflow.com/questions/9503658

Вопрос

Я ищу возможности для увеличения параллелизма и производительности в My Scala 2.9 / Akka 2.0 RC2 Code. Учитывая следующий код:

import akka.actor._

case class DataDelivery(data:Double)

class ComputeActor extends Actor {
    var buffer = scala.collection.mutable.ArrayBuffer[Double]()

    val functionsToCompute = List("f1","f2","f3","f4","f5")
    var functionMap = scala.collection.mutable.LinkedHashMap[String,(Map[String,Any]) => Double]()  
    functionMap += {"f1" -> f1}
    functionMap += {"f2" -> f2}
    functionMap += {"f3" -> f3}
    functionMap += {"f4" -> f4}
    functionMap += {"f5" -> f5}

    def updateData(data:Double):scala.collection.mutable.ArrayBuffer[Double] = {
        buffer += data
        buffer
    }

    def f1(map:Map[String,Any]):Double = {
//    println("hello from f1")
      0.0
    }

    def f2(map:Map[String,Any]):Double = {
//    println("hello from f2")
      0.0
    }

    def f3(map:Map[String,Any]):Double = {
//    println("hello from f3")
      0.0
    }

    def f4(map:Map[String,Any]):Double = {
//    println("hello from f4")
      0.0
    }

    def f5(map:Map[String,Any]):Double = {
//    println("hello from f5")
      0.0
    }

    def computeValues(immutableBuffer:IndexedSeq[Double]):Map[String,Double] = {
        var map = Map[String,Double]()
        try {
            functionsToCompute.foreach(function => {
                val value = functionMap(function)
                function match {
                    case "f1" =>
                        var v = value(Map("lookback"->10,"buffer"->immutableBuffer,"parm1"->0.0))
                        map += {function -> v}
                    case "f2" =>
                        var v = value(Map("lookback"->20,"buffer"->immutableBuffer))
                        map += {function -> v}
                    case "f3" =>
                        var v = value(Map("lookback"->30,"buffer"->immutableBuffer,"parm1"->1.0,"parm2"->false))
                        map += {function -> v}
                    case "f4" =>
                        var v = value(Map("lookback"->40,"buffer"->immutableBuffer))
                        map += {function -> v}
                    case "f5" =>
                        var v = value(Map("buffer"->immutableBuffer))
                        map += {function -> v}
                    case _ => 
                        println(this.unhandled())
                }
            })
        } catch {
            case ex: Exception =>
              ex.printStackTrace()
        }
        map
    }

    def receive = {
      case DataDelivery(data) =>
        val startTime = System.nanoTime()/1000
        val answers = computeValues(updateData(data))
        val endTime = System.nanoTime()/1000
        val elapsedTime = endTime - startTime
        println("elapsed time is " + elapsedTime)
        // reply or forward
      case msg =>
        println("msg is " + msg)
    }

}

object Test {
    def main(args:Array[String]) {
        val system = ActorSystem("actorSystem") 
        val computeActor = system.actorOf(Props(new ComputeActor),"computeActor")
        var i = 0
        while (i < 1000) {  
            computeActor ! DataDelivery(i.toDouble)
            i += 1
        }
    }
}
.

Когда я запускаю этот выход (преобразован в микросекунды), это

elapsed time is 4898
elapsed time is 184
elapsed time is 144
    .
    .
    .
elapsed time is 109
elapsed time is 103
.

Вы можете увидеть инкрементный компилятор JVM, пинающий.

Я думал, что одна быстрая победа может быть изменение

    functionsToCompute.foreach(function => {
.

к

    functionsToCompute.par.foreach(function => {
.

Но это приводит к следующим истеченным временам

elapsed time is 31689
elapsed time is 4874
elapsed time is 622
    .
    .
    .
elapsed time is 698
elapsed time is 2171
.

<Сильная> Некоторые информация:

1) Я работаю на MacBook Pro с 2 ядрами.

2) В полной версии функции представляют собой длительные работы, которые петля по порциям мультипликационного общего буфера. Это не может быть проблемой, поскольку извлечение сообщений от почтового ящика актера контролирует поток, но я подозреваю, что это может быть проблемой с повышенным параллелизмом. Вот почему я преобразовал в IndexedSeq.

3) В полной версии функциональный список может варьироваться, чтобы не все элементы в функциональности функции обязательно вызываются (I.e.) Функциональная функция. Также может быть намного больше, чем функция функции. Также

4) Функции могут быть вычислены параллельно, но результирующая карта должна быть завершена перед возвратом

<Сильные> Некоторые вопросы:

1) Что я могу сделать, чтобы сделать параллельную версию бегать быстрее?

2) Где бы он имел смысл добавить неблокирующие и блокирующие фьючерсы?

3) Где бы он имел смысл пересылать вычисление к другому актеру?

4) Каковы некоторые возможности для увеличения неподумности / безопасности?

Спасибо, Брюс

Это было полезно?

Решение

Предоставление примера в соответствии с запросом (извините за задержку ... У меня нет уведомлений на так).

Есть большой пример в документации Akka

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top