J'écris une bibliothèque algébra linéaire (simple!). Dans la mise en œuvre de Multiplication Matrix , un Visualvm échantillon de performance me dit que l'algorithme dépense 85% de son temps (" moi-même ", spécifiquement) dans la méthode suivante lorsqu'il multiplie les grandes matrices (5K x 120K):
public double next() { double result; if(hasNext()) //* 0 0:aload_0 //* 1 1:invokevirtual #88 <Method boolean hasNext()> //* 2 4:ifeq 32 result = vis[i++].next(); // 3 7:aload_0 // 4 8:getfield #42 <Field VectorIterator[] vis> // 5 11:aload_0 // 6 12:dup // 7 13:getfield #28 <Field int i> // 8 16:dup_x1 // 9 17:iconst_1 // 10 18:iadd // 11 19:putfield #28 <Field int i> // 12 22:aaload // 13 23:invokeinterface #72 <Method double VectorIterator.next()> // 14 28:dstore_1 else //* 15 29:goto 42 throw new IllegalStateException("No next value"); // 16 32:new #89 <Class IllegalStateException> // 17 35:dup // 18 36:ldc1 #91 <String "No next value"> // 19 38:invokespecial #93 <Method void IllegalStateException(String)> // 20 41:athrow return result; // 21 42:dload_1 // 22 43:dreturn }
3 Réponses :
Je ne connais pas Visualvm à partir de l'expérience. P>
Déterminez d'abord si son instrumentation du bytecode pour recueillir des statistiques. Si tel est le cas, ne cherchez pas d'autre manière - l'instrumentation d'une méthode courte ne fait toujours pas surexulser son temps en soi (mesurer le temps et l'incrémentation du compteur de statistiques coûte plus de temps que la méthode elle-même). P>
Mais c'est toujours possible que l'itérateur consomme plus de temps que le calcul lui-même. Imaginez juste résumer une matrice. L'ajout d'une valeur de flotteur à une somme locale variable coûte beaucoup moins de temps que d'appeler une méthode, en vérifiant un invariant et d'accéder à la matrice. P>
Je viens de vérifier la documentation de Visualvm. C'est un profileur d'instrumentation.
Cependant, je pense que je l'utilise dans le mode "Échantillonnage", ce qui signifie qu'il devrait "geler" la CPU périodiquement (probablement des dizaines ou des centaines de fois par seconde) puis de voir ce qui se passe à exécuter sur chaque fil de ce processus dans ce processus à ce moment-là. C'est une approche assez insuffisive (de l'expérience) et ne devrait pas gonfler arbitrairement le temps passé dans cette méthode, imo.
Eh bien, je ne connais pas Visualvm, mais la documentation indique "lors de l'analyse des performances de l'application, Visualvm Instruments toutes les méthodes i> de l'application profilée" sous le profilage de la CPU ( visualvm.java.net/profiler.html ). Vous ne savez pas si c'est ce que vous faites ou si vous utilisez une autre option?
Il y a une option "échantillonneur" que j'utilise qui est différente de l'option "Profiler", c'est pourquoi je crois que son échantillonnage. Il ne semble pas être couvert par le guide en ligne, malheureux. Vous pouvez voir une capture d'écran de l'option ici pour référence.
L'échantillonnage n'utilise pas d'instrumentation.
@Tomashurka merci de répéter l'évidence
oublier le profileur. Il suffit de mettre en pause la chose à plusieurs reprises et examinez la pile. Si 85% du temps passe dans cette routine, les chances sont de 85% sur chaque pause que vous verrez exactement où il se trouve dans cette routine et exactement d'où vient. Vous pouvez même voir où il est en train de multiplier les matrices. Des milliers d'échantillons ne vous diront pas ça. P>
mon propre sens est que l'appelant cette fonction, alors faire hasnext code>, puis effectuez
suivant code> sur chaque élément em> va être beaucoup plus lent que
i ++ code>. p>
J'ai compris que cette méthode ressemblait à un point chaud car VisualvM était instructuré d'ignorer les méthodes de la JRE dans son profilage. Le temps passé dans ces méthodes "ignorées" était (ostensiblement) étant roulée dans le temps en soi de la saisie non ignorée la plus haute de la pile d'appel. P>
ci-dessous est l'écran de réglages de VisualVM, y compris le paramètre "Ne pas profil de profil" qui apportait les données erronées. Pour ajuster les paramètres "Ignorer la classe", vous devez (1) cliquer sur la case "Paramètres" en surbrillance en rouge, puis (2) Ajuster le paramètre Classes en surbrillance en bleu. P>
P>
Selon ce que vous faites, il est probablement de sens au moins de ne pas ignorer le Java. * code> et
javax. * code> paquets. P>
Je suppose que cela dépend vraiment des appels de hasnext () et suivants () puisque nous ne connaissons pas les objets sous-jacents que je ne peux pas supposer qu'ils sont O (1) et que la méthode doit être assez rapide, ce qu'elle pourrait se contenter de la Sun 1000X pour tout ce que nous savons
@RuntimeError, "moi-temps" devrait i> n'incluez que le temps passé à l'intérieur de la méthode elle-même, donc le
hasnext () code> et le sous-
suivant () code> Les appels Devraient I> n'ont rien à voir avec le temps de soi attribué à cette méthode, autant que je sache. (S'il vous plaît corrigez-moi si vous savez différemment!)
Est
suivant code> s'appelant (récursif)? Ce serait une bonne raison pour laquelle il faut du temps si la récursion est profonde ...
@assylias non, ce n'est pas le cas. La méthode
suivante () code> que ce
suivant () code> Les appels sont dans une classe différente. Grand point, cependant.
@sigpwedned Votre méthode est assez courte, donc il est probablement inliné à un moment donné, qui pourrait confondre le profileur .