2014-07-02 4 views
2

J'ai le code suivant:cadre de lecture: Async vs performances Sync

def sync = Action { 
     val t0 = System.nanoTime() 
     Thread.sleep(100) 
     val t1 = System.nanoTime() 
     Ok("Elapsed time: " + (t1 - t0)/1000000.0 + "ms") 
    } 

    def async = Action { 
    val t0 = System.nanoTime() 
    Async { 
      Future{ 
      Thread.sleep(100) 
      val t1 = System.nanoTime() 
      Ok("Elapsed time: " + (t1 - t0)/1000000.0 + "ms") 
      } 
    } 
    } 
Différence

entre code ci-dessus est que la synchronisation dormira sur le fil qui a reçu la demande et async dormira sur le fil séparé de sorte que le fil en charge de recevoir une demande peut continuer à recevoir des demandes sans bloquer. Lorsque je profile le thread, je vois une augmentation soudaine du nombre de threads créés pour les requêtes asynchrones comme prévu. Cependant, les deux méthodes ci-dessus avec une rampe de connexion simultanée de 20 secondes entraînent le même débit et la même latence. Je m'attendais à ce que l'async fonctionne mieux. Pourquoi cela serait-il?

+0

Ils sont tous les deux vraiment la même chose. http://stackoverflow.com/questions/23997418/are-there-any-benefits-in-using-non-async-actions-in-play-framework-2-2/24004444#24004444 –

Répondre

4

La réponse courte est que les deux méthodes sont essentiellement les mêmes. Les actions elles-mêmes sont toujours asynchrones (voir documentation on handling asynchronous results).

Dans les deux cas, l'appel sleep se produit dans le pool de threads de l'action (ce qui n'est pas optimal).

Comme indiqué dans Understanding Play thread pools:

cadre de lecture est, de bas en haut, un framework web asynchrone. Les flux sont gérés de manière asynchrone en utilisant des itérés. Les pools de threads dans Play sont configurés pour utiliser moins de threads que dans les frameworks Web traditionnels, car les E/S de play-core ne se bloquent jamais. Pour cette raison, si vous envisagez d'écrire du code d'E/S bloquant, ou du code susceptible d'effectuer beaucoup de travail intensif sur le processeur, vous devez savoir exactement quel pool d'unités d'exécution porte ce workload, et vous devez l'ajuster en conséquence .

Par exemple, ce fragment de code utilise un pool de threads séparés:

Future { 
    // Some blocking or expensive code here 
}(Contexts.myExecutionContext) 

Comme des ressources supplémentaires, voir this answer et this video pour plus d'informations sur la gestion des actions asynchrones et this et this messages du forum pour des discussions approfondies sur l'objet.

+1

Le webinaire était génial! Merci! http://www.youtube.com/watch?v=cnPPLpIk9mo&feature=youtu.be&t=15m22s – Mayumi

+0

En effet. J'ai ajouté le lien à la vidéo à la réponse. –