Quand plus de performance entraine des temps d’exécution plus longs…

Supposons que vous travailliez sur un problème de performance d’un scénario sur un serveur et que, suite à une première campagne de suppression des goulets d’étranglements, vous ayez réussi à abaisser le temps total d’exécution du scénario.

La plupart des temps unitaires d’exécution des requêtes ont baissé, le nombre de scénarios joués en parallèle dans le même temps augmente, etc. Tout se passe donc a priori dans le bon sens, mais vous vous rendez compte que certaines requêtes prennent plus de temps. Et pas seulement relativement au scénario dans son ensemble, mais en temps absolu. Les performances sont globalement meilleures, mais certains temps d’exécution s’allongent !

image

Surtout, vous vous rendez compte que ce n’est pas un effet de bord sur un temps unitaire, mais bien sur une moyenne pour une requête particulière. Comment est-ce possible ?

Une des raisons possibles est que l’augmentation des performances globales fait que plus de threads peuvent être menées en parallèle, et plus de jeux de scénarios peuvent être exécutés de manière rapprochée. Au final, des verrous qui, avec un flux faible étaient invisibles, peuvent devenir prépondérant, et ainsi ralentir les opérations associées.

Un petit graphe temporel pour expliquer ceci : avant optimisation, les instances se succèdent à un rythme faible, et le lock est pour ainsi dire nul.

image

Prenons maintenant le même graphe où le throughput a fortement augmenté, car les goulets d’étranglements principaux ont été supprimés. On peut alors se retrouver avec ce genre de graphique :

image

La période de recouvrement est alors beaucoup plus longue et que se passe-t-il alors ? Si vous avez malheureusement une contention sur une ressource unique, le second service devra attendre la fin du premier, ou en tout cas le moment où il relâche cette ressource, pour continuer, ralentissant ainsi son exécution. Si la période de recouvrement augmente, on peut arriver à des extrêmes comme ceci :

image

Les zones en rouge montrent l’exécution effective de la requête, en supposant une ressource unique partagée, et relâchée seulement en toute fin d’exécution. Les lignes bleues montrent alors le temps total d’exécution perçue pour une requête donnée. On voit bien que plus de throughtput (et donc des lancements plus rapprochés) peuvent dans certains cas provoquer une durée au final plus longue, alors que globalement, la performance reste meilleure, au sens où il est possible de tirer plus de scénarios dans le même temps, à machine équivalente…

En conclusion : attention à la façon dont on mesure la performance. En cas de doute, toujours revenir aux bases : comment est-ce que la performance est perçue par le client ?

About JP Gouigoux

Jean-Philippe Gouigoux est Architecte Logiciel, MVP Connected Systems Developer. Il intervient régulièrement à l'Université de Bretagne Sud ainsi qu'à l'Agile Tour. Plus de détails sur la page "Curriculum Vitae" de ce blog.
This entry was posted in Performance and tagged . Bookmark the permalink.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha Captcha Reload