Votre question est horriblement incomplète, mais de ce que nous pouvons le deviner, il est tout à fait plausible que la deuxième variante prend plus de temps, si l'on suppose que currencyConvCF
représente une opération asynchrone qui peut s'exécuter simultanément lorsque vos fragments de code sont exécutés et que vous parlez du temps total nécessaire pour effectuer toutes les opérations, y compris celui représenté par le CompletableFuture
renvoyé par thenApplyAsync
(earlyEarningsInHomeCountryCF
).
Dans la première variante, vous appelez getYearlyEarningForUserWithEmployer
alors que l'opération représentée par currencyConvCF
est peut-être toujours en cours d'exécution. La multiplication aura lieu lorsque les deux opérations seront terminées.
Dans la deuxième variante, l'invocation getYearlyEarningForUserWithEmployer
fait partie de l'opération est passé à currencyConvCF.thenApplyAsync
, donc il ne démarre pas avant que l'opération représentée par currencyConvCF
est terminée, donc aucune opération se déroulera en même temps. Si nous supposons que getYearlyEarningForUserWithEmployer
prend un temps significatif, disons une seconde, et n'a pas de dépendances internes à l'autre opération, il n'est pas surprenant quand l'opération globale prend plus de temps dans cette variante.
Il semble, en fait ce que vous voulez faire est quelque chose comme:
CompletableFuture<Double> earlyEarningsInHomeCountryCF = currencyConvCF.thenCombineAsync(
CompletableFuture.supplyAsync(
() -> employmentService.getYearlyEarningForUserWithEmployer(userId, emp.getId())),
(currencyConv, yearlyEarnings) -> currencyConv * yearlyEarnings);
si getYearlyEarningForUserWithEmployer
n'est pas exécuté de façon séquentielle dans le thread initiant mais les deux opérations de source peuvent fonctionner de manière asynchrone avant la multiplication finale s'applique.
Cependant, lorsque vous appelez get
immédiatement après dans le thread initiateur, comme dans votre code lié sur github, ce traitement asynchrone de la seconde opération n'a aucun avantage. Au lieu d'attendre l'achèvement, votre thread initiateur peut simplement effectuer l'opération indépendante comme le fait déjà la deuxième variante de code de votre question et vous serez probablement encore plus rapide lorsque vous ne lancez pas une opération asynchrone pour quelque chose d'aussi simple qu'une simple multiplication. à la place:
CompletableFuture<Double> currencyConvCF = /* a true asynchronous operation */
return employmentService.getYearlyEarningForUserWithEmployer(userId, emp.getId())
* employerCurrencyCF.join();
Pouvez-vous donner un extrait de employmentService.getYearlyEarningForUserWithEmployer() – Naruto
Comment cela fait-il la différence? – Robin
Veuillez faire un [mcve]. – Tunaki