Question Efficacité d'avoir une logique en ligne vs appeler une méthode?


Je suis actuellement en désaccord avec mon professeur de 2ème année JAVA que j'espère que vous pourrez aider à résoudre:

Le code avec lequel nous avons commencé était le suivant:

   public T peek()
   {
       if (isEmpty())
       .........
   }
   public boolean isEmpty() 
   {
       return topIndex<0;
   }

Et elle veut que nous enlevions le isEmpty() référence et placer son code directement dans le if déclaration (c'est-à-dire modifier le contenu de la méthode de peek pour: if(topIndex<0).......) pour "rendre le code plus efficace". J'ai soutenu que a) l’optimiseur de temps d’exécution / de compilation aurait très probablement intégré la isEmpty() call, b) même si ce n'était pas le cas, les opérations de 5 à 10 machines seraient négligeables dans presque toutes les situations, et c) c'est simplement un mauvais style car cela rend le programme moins lisible et moins changeant.

Donc, je suppose que ma question est la suivante: Y a-t-il une efficacité d'exécution obtenue en intégrant la logique plutôt que d'appeler une méthode? J'ai essayé des techniques de profilage simples (aka boucle longue et chronomètre) mais les tests n'ont pas été concluants.

MODIFIER:

Merci à tous pour les réponses! J'apprécie que vous ayez tous pris le temps. Aussi, j'apprécie ceux d'entre vous qui ont commenté le pragmatisme de discuter avec mon professeur et surtout de le faire sans données. @ Mike Dunlavey J'apprécie votre perspicacité en tant qu'ancien professeur et vos conseils sur la séquence de codage appropriée. @ya_pulser J'apprécie tout particulièrement les conseils de profilage et les liens que vous avez pris le temps de partager.


11
2017-10-03 10:30


origine


Réponses:


Vous avez raison dans vos hypothèses concernant le comportement du code Java, mais vous êtes impoli envers votre professeur en train de discuter sans données :). Argumenter sans données est inutile, prouver vos hypothèses avec des mesures et des graphiques.

Vous pouvez utiliser JMH ( http://openjdk.java.net/projects/code-tools/jmh/ ) pour créer un petit repère et mesurer la différence entre:

  • inséré à la main (enlevez la méthode isEmpty et placez le code dans l’appel)
  • Inline par java jit compiler (hotspot après 100k (?) invocations - voir sortie de compilation jit print)
  • hotspot désactivé inlining du tout

Lisez s'il vous plaît http://www.oracle.com/technetwork/java/whitepaper-135217.html#méthod 

Les paramètres utiles pourraient être:

  • -Djava.compiler = AUCUN
  • -XX: + PrintCompilation

De plus, chaque version de jdk a son propre ensemble de paramètres pour contrôler jit.

Si vous créez des graphiques en tant que résultats de vos recherches et que vous les présenterez poliment au professeur, je pense que cela vous sera bénéfique à l’avenir.

je pense que https://stackoverflow.com/users/2613885/aleksey-shipilev peut aider avec les questions liées à jmh.

BTW: J'ai eu beaucoup de succès lorsque j'ai inséré beaucoup de méthodes dans une boucle de code unique pour atteindre la vitesse maximale pour la routine de propagation de réseau neuronal parce que java est (était?) Trop fainéant pour intégrer des méthodes avec des méthodes. C'était inconcevable et rapide :(.


9
2017-10-03 11:40



Triste...

Je suis d'accord avec vos intuitions à ce sujet, en particulier "les opérations de la machine 5-10 seraient négligeables dans presque toutes les situations".

J'ai été professeur à la SC il y a longtemps. D'une part, les professeurs ont besoin de tout ce que vous pouvez leur donner. L'enseignement est très exigeant. Vous ne pouvez pas passer une mauvaise journée. Si vous vous présentez à un cours et que vous n'êtes pas complètement préparé, vous allez faire un tour difficile. Si vous faites un test vendredi et que vous n'avez pas les notes lundi, les élèves diront "Mais vous avez passé tout le week-end!" Vous pouvez obtenir de la satisfaction en voyant vos élèves apprendre, mais vous n'apprenez pas beaucoup, sauf comment enseigner.

D'autre part, peu de professeurs ont beaucoup d'expérience pratique avec de vrais logiciels. Ainsi, leurs opinions ont tendance à être fondées sur diverses certitudes dogmatiques plutôt que sur un pragmatisme solide.

La performance en est un exemple parfait. Ils ont tendance à dire "Ne faites pas X. Faites Y parce que cela fonctionne mieux." qui manque complètement le point sur les problèmes de performance - vous devez faire face à les fractions, ne pas absolus. Tout dépend de quoi autre qui se passe. La façon d'aborder la performance est, comme quelqu'un l'a dit: «Tout d'abord, faites les choses correctement. alors faites vite. "

Et la manière dont vous accélérez le processus ne consiste pas à regarder le code (et à vous demander si je devrais le faire ou devrais-je le faire), mais en le lançant et en le laissant vous dire comment il passe du temps. L'idée de base de profilage C'est comme ça que tu fais ça. Il existe maintenant un mauvais profilage et un bon profilage, comme expliqué dans la deuxième réponse ici (et généralement quand les professeurs faire enseigner le profilage, ils enseignent le mauvais type), mais c'est la voie à suivre.


8
2017-10-03 15:25



Comme vous le dites, la différence sera faible et, dans la plupart des cas, la lisibilité devrait être une priorité plus élevée. Dans ce cas cependant, puisque la méthode supplémentaire consiste en une seule ligne, je ne suis pas sûr que cela ajoute un réel avantage de lisibilité, sauf si vous appelez la même méthode depuis un autre endroit.

Cela dit, rappelez-vous que l'objectif de votre enseignant est de vous aider à apprendre l'informatique, et que cette priorité est différente de celle de l'écriture de code de production. En particulier, elle ne veut pas que vous laissiez l’optimisation aux outils automatisés, car cela n’aide pas votre apprentissage.

Aussi, juste une note pratique - à l'école et dans le développement professionnel, nous devons tous respecter les normes de codage avec lesquelles nous ne sommes pas d'accord. C'est une compétence importante, et est vraiment nécessaire pour le travail en équipe, même si cela fait mal.


5
2017-10-03 10:45



Appel isEmpty est idiomatique et bien lisible. Insertion manuelle qui serait une micro optimisation, quelque chose de mieux fait dans les situations critiques de performance, et après qu'un goulot d'étranglement a été confirmé par l'analyse comparative dans l'environnement de production prévu.

Y a-t-il un réel avantage en termes de performance dans l'insertion manuelle? Théoriquement oui, et c'est peut-être ce que la conférence voulait souligner. En pratique, Je ne pense pas que vous trouverez une réponse absolue. Le comportement d'inclinaison automatique peut dépendre de l'implémentation. Gardez également à l'esprit que les résultats des tests dépendront de la mise en œuvre, de la version et de la plate-forme de JVM. Et pour cette raison, ce type d'optimisation peut être utile dans des situations extrêmes rares, et en général préjudiciable à la portabilité et à la maintenabilité.

Par la même logique, devrions-nous intégrer toutes les méthodes, éliminer toutes les indirections au détriment de la duplication de gros blocs de code? Définitivement pas. Là où vous tracez exactement la ligne entre décomposition et incrustation, cela peut aussi dépendre de vos goûts personnels. dans une certaine mesure.


3
2017-10-03 11:01



Une autre forme de données à examiner pourrait être le code généré. Voir le -XX:+PrintAssembly option et amis. Voir Comment voir le code compilé par JIT dans JVM? pour plus d'informations.

Je suis convaincu que dans ce cas particulier, la JVM Hotspot intégrera l'appel à isEmpty et il n'y aurait pas de différence de performance.


0
2018-03-13 16:10