Le benchmarking du chronomètre est-il acceptable?

Quelqu’un a-t-il déjà recours à l’parsing comparative du chronomètre ou un outil de performance doit-il toujours être utilisé? Existe-t-il de bons outils gratuits pour Java? Quels outils utilisez-vous?

Pour clarifier mes préoccupations, l’parsing comparative du chronomètre est sujette à des erreurs dues à la planification du système d’exploitation. Sur une exécution donnée de votre programme, le système d’exploitation peut programmer un autre processus (ou plusieurs) au milieu de la fonction que vous programmez. En Java, les choses sont encore un peu moins bonnes si vous essayez de synchroniser une application threadée, car le planificateur JVM injecte un peu plus de hasard dans le mixage.

Comment abordez-vous la planification du système d’exploitation lors de l’parsing comparative?

L’parsing comparative du chronomètre est bien, à condition que vous mesuriez suffisamment d’itérations pour avoir un sens. Généralement, j’ai besoin d’un temps total écoulé d’un certain nombre de secondes à un chiffre. Sinon, vos résultats sont facilement faussés par la planification et par d’autres interruptions du système d’exploitation.

Pour cela, j’utilise un petit ensemble de méthodes statiques construites il y a longtemps, qui sont basées sur System.currentTimeMillis() .

Pour le travail de profilage, j’ai utilisé jProfiler pendant plusieurs années et je l’ai trouvé très bon. J’ai récemment examiné YourKit , qui semble génial du site Web, mais je ne l’ai pas utilisé du tout, personnellement.

Pour répondre à la question sur les interruptions de planification, je trouve que des exécutions répétées jusqu’à ce que la cohérence soit atteinte / observées fonctionnent en pratique pour éliminer les résultats anormaux de la planification des processus. Je trouve également que la planification des threads n’a pas d’impact pratique pour des durées comsockets entre 5 et 30 secondes. Enfin, après avoir dépassé les quelques secondes, le calendrier a, selon mon expérience, un impact négligeable sur les résultats. Je trouve qu’une moyenne de 5 secondes est identique à une durée de 5 minutes pour le temps / itération.

Vous pouvez également envisager de lancer le code testé environ 10 000 fois pour “échauffer” le JIT, en fonction du nombre de fois que le code testé doit être exécuté dans le temps.

C’est totalement valable tant que vous mesurez des intervalles de temps suffisamment importants. J’exécuterais 20-30 passages de ce que vous avez l’intention de tester pour que le temps total écoulé dépasse 1 seconde. J’ai remarqué que les calculs de temps basés sur System.currentTimeMillis () ont tendance à être 0 ms ou ~ 30 ms; Je ne pense pas que vous pouvez obtenir quelque chose de plus précis que cela. Vous pouvez essayer System.nanoTime () si vous avez vraiment besoin de mesurer un petit intervalle de temps:

Un profileur vous donne des informations plus détaillées, ce qui peut aider à diagnostiquer et à corriger les problèmes de perf.

En termes de mesure réelle, le temps de chronométrage est ce que les utilisateurs remarquent, donc si vous voulez valider que les choses sont dans des limites acceptables, le chronomètre est correct.

Lorsque vous souhaitez résoudre des problèmes, un profileur peut être très utile.

Chronomètre est en fait le meilleur benchmark!

Le temps de réponse réel de l’utilisateur final est le temps qui compte réellement.

Il n’est pas toujours possible d’obtenir ce temps en utilisant les outils disponibles, par exemple la plupart des outils de test n’incluent pas le temps nécessaire à un navigateur pour rendre une page. outils, mais 5 secondes plus le temps de réponse à l’utilisateur.

Les outils sont parfaits pour les tests automatisés et pour la détermination des problèmes, mais ne perdez pas de vue ce que vous voulez vraiment mesurer.

Vous devez tester un nombre réaliste d’itérations car vous obtiendrez des réponses différentes selon la manière dont vous testez le timing. Si vous effectuez une opération une seule fois, il peut être trompeur de prendre la moyenne de nombreuses itérations. Si vous souhaitez connaître le temps nécessaire à l’échauffement de la JVM, vous pouvez exécuter plusieurs itérations (par exemple 10 000) qui ne sont pas incluses dans les délais.

Je vous suggère également d’utiliser System.nanoTime () car c’est beaucoup plus précis. Si votre temps de test est d’environ 10 microsecondes ou moins, vous ne voulez pas appeler cela trop souvent ou cela peut changer votre résultat. (par exemple, si je teste par exemple 5 secondes et que je veux savoir quand ceci est terminé, je ne reçois que le nanoTime toutes les 1000 itérations, si je sais qu’une itération est très rapide)

Les profileurs peuvent gêner le chronométrage et utiliser une combinaison de chronomètres pour identifier les problèmes de performance généraux, puis utiliser le profileur pour déterminer le temps passé. Répéter au besoin.

J’ai exécuté un programme aujourd’hui qui a recherché et collecté des informations à partir d’un tas de fichiers dBase, il a fallu un peu plus d’une heure pour s’exécuter. J’ai jeté un coup d’oeil au code, j’ai fait une estimation éclairée du goulot d’étranglement, j’ai apporté une légère amélioration à l’algorithme et j’ai relancé le programme, cette fois en 2,5 minutes. Je n’ai pas eu besoin d’outils de profilage ou de suites de tests sophistiqués pour me dire que la nouvelle version constituait une amélioration significative. Si j’avais besoin d’optimiser encore le temps d’exécution, j’aurais probablement fait des parsings plus sophistiquées, mais ce n’était pas nécessaire. Je trouve que ce type de «benchmarking» de chronomètre est une solution acceptable dans un certain nombre de cas et le recours à des outils plus avancés prendrait plus de temps dans ces cas.

Après tout, c’est probablement la deuxième forme d’parsing comparative la plus populaire, juste après le «benchmarking sans surveillance» – où nous disons que «cette activité semble lente, qu’elle semble rapide».

Le plus important à optimiser est généralement ce qui interfère avec l’expérience de l’utilisateur – qui dépend le plus souvent de la fréquence à laquelle vous effectuez l’action et de tout ce qui se passe en même temps. D’autres formes de benchmarking aident souvent à ne pas les identifier.

Je pense qu’une question clé est la complexité et la durée de l’opération.

J’utilise même parfois des mesures physiques de chronomètre pour voir si quelque chose prend des minutes, des heures, des jours ou même des semaines pour calculer (je travaille avec une application où les durées de plusieurs jours ne sont pas inconnues, même si les temps les plus courants).

Cependant, l’automatisation offerte par les appels à n’importe quel système d’horloge sur l’ordinateur, comme l’appel java millis mentionné dans l’article lié, est nettement supérieure à la visualisation manuelle de la durée d’exécution de quelque chose.

Les profileurs sont agréables lorsqu’ils fonctionnent, mais j’ai eu des difficultés à les appliquer à notre application, qui implique généralement la génération de code dynamic, le chargement dynamic de DLL et le travail effectué dans les deux langages de script compilés juste à temps de mon application. Ils se limitent souvent à une seule langue source et à d’autres attentes irréalistes pour des logiciels complexes.

Comment abordez-vous la planification du système d’exploitation lors de l’parsing comparative?

Faites un benchmark assez long sur un système représentatif de la machine que vous utiliserez. Si votre système d’exploitation ralentit votre application, cela devrait faire partie du résultat.

Il ne sert à rien de dire que mon programme serait plus rapide, si seulement je n’avais pas de système d’exploitation.

Si vous utilisez Linux , vous pouvez utiliser des outils tels que numactl , chrt et taskset pour contrôler la manière dont les processeurs sont utilisés et la planification.

Je ne pense pas que l’parsing comparative de chronomètre est trop horrible, mais si vous pouvez accéder à une machine Solaris ou OS X, vous devriez vérifier DTrace. Je l’ai utilisé pour obtenir d’excellentes informations sur le timing dans mes applications.

J’utilise toujours l’parsing comparative du chronomètre car c’est beaucoup plus facile. Les résultats ne doivent pas nécessairement être très précis pour moi. Si vous avez besoin de résultats précis, vous ne devriez pas utiliser l’parsing comparative du chronomètre.

Je le fais tout le temps. Je préférerais plutôt utiliser un profileur, mais le fournisseur du langage spécifique au domaine avec lequel je travaille ne le fournit pas.