2009-10-15 6 views
1

J'ai cette application .NET, qui repose sur l'exécution différée. Quand je le profile, les méthodes qui consomment le plus de temps sont celles qui énumèrent les IEnumerables. Pour cette raison, je pense que les méthodes qui doivent être optimisées ne sont pas dans les méthodes Top Time Consuming.Comment profiler une application lorsque l'exécution différée le rend difficile?

Vous est-il déjà arrivé? Comment profiler une application correctement dans cette situation?

+0

Bannissement tardif ou exécution différée? –

+0

@Andrew Merci, j'ai oublié un instant les bons mots pour cela. –

+0

Quels outils de profilage utilisez-vous? –

Répondre

0

Dans une application simple comme celle ci-dessous, il n'est pas si difficile de le profiler. Mais dans des applications plus complexes, je n'ai pas encore trouvé la cause du retard.

Le programme suivant:

static IEnumerable<int> TimeConsuming() 
{ 
    foreach (var i in Enumerable.Range(0, 10000)) 
    { 
     Thread.Sleep(1); 
     yield return i; 
    } 
} 

static void Enumerates(IEnumerable<int> enumerable) 
{ 
    enumerable.ToArray(); 
} 

static void Main(string[] args) 
{ 
    var enumerable = TimeConsuming(); 
    Enumerates(enumerable); 
} 

Lorsque l'instrumentation profilée montre la cause correcte du retard:

 
Function Name            Inclusive Time % 
ConsoleApplication1.Program.Main(string[])      99.60 
ConsoleApplication1.Program.<TimeConsuming>d__0.MoveNext()  99.89 
1

Jader, si vous pouvez exécuter l'application sous un IDE et une pause au hasard, il est un moyen peu orthodoxe mais très rapide et efficace pour savoir ce qui est responsable de l'époque. Quelques personnes le savent, et j'ai essayé de l'expliquer longuement. Here's my latest attempt. Bonne chance. Here's another explanation et an example.

AJOUTÉ: Dans votre commentaire, vous avez dit que c'est exactement ce que font les profileurs d'échantillonnage, mais plus rapidement. Même si elles échantillonnent en fait l'ensemble de la pile d'appel, il y a deux grands problèmes:

  1. Ils résument, souvent au niveau des fonctions ou des méthodes, ce qui signifie que vous devez chasser dans les fonctions du temps pour trouver les déclarations qui prennent beaucoup de temps. Pendant que vous recherchez cette information, les échantillons de pile l'ont effectivement mais ne vous l'ont pas montré. La raison en est qu'il y a trop d'échantillons à examiner, alors ils doivent résumer. Cependant, si une déclaration est sur la pile d'appel un certain pourcentage de temps, comme 50% (ce qui n'est pas inhabituel), alors c'est exactement ce qui serait sauvé par sa suppression, et c'est à peu près le pourcentage d'échantillons qui la contiennent. Dix échantillons le montreraient aussi sûrement que 1000, de sorte que les échantillons supplémentaires sont gaspillés, et l'effort pour inclure leurs informations ne fait que provoquer l'obscurcissement. Certains profileurs résument au niveau des états, et qui est une amélioration, mais il se heurte à la deuxième question:

  2. Vous devez savoir la raison pour laquelle le code de temps est en cours d'exécution, et que l'information ne vous est pas montrée. L'information est là, dans les échantillons de la pile. Si une déclaration est sur la pile d'appels sur une partie des échantillons, il suffit de regarder un ou plusieurs de ces échantillons. La pile d'appel vous donne la chaîne de justification de la raison pour laquelle l'instruction est en cours d'exécution. Puisque vous savez pourquoi cela est fait, vous pouvez dire s'il y a une autre façon d'accomplir la même chose qui ne prend pas beaucoup de temps, comme utiliser des données mises en cache à partir d'une invocation préalable de cette instruction. Certains profileurs vous donnent un arbre d'appel ou un graphe d'appel, mais ce sont des résumés, ce qui signifie que vous devez encore énoncer exactement la raison pour laquelle la déclaration est appelée la plupart du temps.

J'espère que cela vous donne une idée de ce que je veux dire. L'idée générale que vous devez agréger et mesurer afin de localiser les problèmes est naturelle, mais il est beaucoup plus efficace d'extraire l'information complète contenue dans un petit nombre d'échantillons informatifs.

P.S. Ne pensez pas que la récursivité est un problème. La récursivité se manifeste par une déclaration apparaissant plus d'une fois dans certains échantillons. Il est toujours vrai que la fraction d'échantillons contenant la déclaration est une estimation de son coût. (Vous pourriez penser à cela pendant une minute.)

Il existe d'autres idées fausses courantes sur la technique (comme son travail sur de petits programmes), qui sont explorées dans les liens ci-dessus.

Questions connexes