9
votes

Puis-je appeler à moindre coût une méthode Java pour obtenir le nom de la méthode actuelle?

Fondamentalement, j'ai une déclaration de journalisation à l'intérieur d'une méthode. Chaque fois que la méthode est appelée, je souhaite appeler facilement le nom de la méthode et l'ajouter à la déclaration de journalisation. Ceci est fait pour minimiser le nombre de lignes codées dures dans mon application. Est-ce que cela est possible de le faire à moindre coût?


2 commentaires

Je ne pense pas qu'il y ait une bonne méthode pouvant être utilisée à l'exécution pour le faire, mais vous pouvez probablement annoter les méthodes nécessitant cette fonctionnalité, puis écrire un processeur d'annotation qui est incorporé dans votre processus de construction. Au moment de l'exécution, cela fonctionnerait presque de manière identique à la codage durement du nom de la méthode, mais vous n'auriez rien à faire de rien.


Dupliqué possible de Obtenir le nom de la méthode d'exécution actuelle


4 Réponses :


15
votes

Non, pas à moindre coût. Le moyen coûteux et unique de le faire est avec un stacktrace méthode. Mieux pour juste le codé.


6 commentaires

Eh bien, c'est dommage. Je ne sais pas pourquoi Java ne peut pas le faire à moindre coût.


Aspectj a été conçu pour traiter des problèmes tels que celui-ci


Comment j'utiliserais Aspectj pour faire quelque chose comme ça? La méthode la plus proche que je puisse trouver est "getourcemethod ()"


Pourquoi devrait-il y avoir être un moyen bon marché de faire cela? Un moyen «bon marché» de faire cela nécessiterait de suivre le nom de la méthode actuelle chaque fois qu'une nouvelle méthode / empilement est entrée / à gauche, ce qui constituerait une dépense inutile de 99,9% du temps. Il serait également gênant lorsque le compilateur JIT incroyable certaines méthodes.


Oui, compte tenu des méthodes d'inlinisation (qui est agressivement réalisée par un JIT moderne pour optimiser des raisons), cela serait assez coûteux pour un cas assez rare - pourquoi une entreprise de journalisation est-elle assez rare sur une version de version optimisée? Si l'on a vraiment besoin de ce genre de choses, annotez simplement les méthodes et générez ces éléments à la compilation - facile et sans frais généraux à l'écart de la journalisation.


Personnellement, je viens de créer une macro dans mon IDE afin que je puisse créer une instruction journalisation comme "log.debug (" $ {actuelMethodName}: ");" Avec quelques keystrokes - Intellij et Eclipse peuvent même être configurés pour laisser le curseur à l'intérieur du devis de droite pour une efficacité maximale



3
votes

Si vous n'avez besoin que de nom de méthode et de numéro de ligne, vous pouvez le faire raisonnablement rapidement. Dans mon micro de référence, vous pouvez faire environ 120000 appels par seconde: xxx

voir aussi Cette réponse .


3 commentaires

Test de chaîne (int i) {StackTraceElement Ste = fil.currentThread (). GetStackTrace () [I]; // string astring = "hleh"; // retourne astring; retour ste.getmethodname (); }} J'ai exécuté entre faire un code dur et faire stacktrace // avec StackTrace // 30.281 secondes //33024.00845414616 Appels / Deuxième // Deuxième exécution //17.937 secondes // 55750 appels / secondaire // secondaire // //0.016 secondes //6.25E7 appels / seconde --- Fondamentalement une augmentation substantielle de 100% de coûts par rapport à un retour de chaîne codé dur


Droit. Mais tout dépend de la fréquence à laquelle ce code est appelé. Dis, si vous appelez cela seulement une fois par seconde, vous pouvez peut-être vous le permettre.


Qu'en est-il d'une annotation ou de quelque chose pour simplement enregistrer le nom de la méthode actuel, afin que je puisse couper en coller la chose sans changer la chaîne stupide et plus?



2
votes

Pourquoi réinventer la roue, java.util.logging.logger utilise xxx pré>

Je doute que vous obtiendrez plus vite que cela. p>

[modifier] pour obtenir Nom de la méthode d'appel d'appel Utilisez, P>

StackTraceElement caller = getCallerStackFrame();
String name = caller != null ? caller.getMethodName() : "<unknown>"


2 commentaires

Cela utilise StackTrace et vous oblige à utiliser le journal Java. C'est bien si vous faites des tests dans une petite application à la maison, mais selon le test exécuté ci-dessous, StackTrace est 100 fois plus lent.


@Travman Je suis d'accord, il vient de demander une méthode externe qu'il pourrait appeler qui retournerait le nom de la méthode des appelants, à l'aide de la codage durement du nom (et de la réflexion [Wooo Bad] apparemment), cette méthode serait la plus rapide. 100 fois n'a pas de cadre de référence cependant et j'imagine que c'est tout discutable et nous poursuivons la fée de micro-optimisation.



1
votes

Avez-vous envisagé d'écrire des messages de journal raisonnables à la place? Je veux dire, des messages qui disent simplement le lecteur de log "Histoire" sur la façon dont le code est exécuté? Les messages qui diffèrent vraiment pour différentes méthodes?

  log4j: some.package.Class1: method1: checkpoint #1
  log4j: some.package.Class1: method1: checkpoint #2
  log4j: some.package.Class2: method2: checkpoint #1
  log4j: some.package.Class2: method2: checkpoint #2


0 commentaires