2009-02-15 8 views
0

Étant donné une interfaceauto-profilage à l'aide classe Proxy

public interface IValueProvider 
{ 
    object GetValue(int index); 
} 

et une structure arborescente des instances de IValueProvider semblables à un arbre d'expression mathématique. Je souhaite mesurer le temps passé dans la méthode GetValue de chaque noeud à l'exécution sans profileur externe. GetValue pourrait faire tout ce que je ne sais pas au moment du design: Collecter des valeurs d'autres IValueProviders, en exécutant une expression IronPython ou même être un plugin externe. Je veux présenter des statistiques sur les horaires des nœuds à l'utilisateur.

Pour cela je peux créer une classe proxy qui encapsule un IValueProvider:

public class ValueProviderProfiler : IValueProvider 
{ 
    private IValueProvider valueProvider; 

    public object GetValue(int index) 
    { 
    // ... start measuring 
    try 
    { 
     return this.valuepProvider.GetValue(index); 
    } 
    finally 
    { 
     // ... stop measuring 
    } 
    } 
} 

Quelle est la meilleure façon de mesurer le temps qui est passer dans un noeud sans distorsions causées par des processus externes, avec une bonne précision et par rapport au fait que les nœuds sont évalués en parallèle? Le simple fait d'utiliser la classe Stopwatch ne fonctionnera pas et le fait de regarder l'heure du processeur ne tient pas compte du fait que le temps CPU aurait pu être consommé sur un autre nœud.

Répondre

0

Vous ne dites pas la rapidité avec laquelle vous vous attendez à chaque appel GetValue pour terminer, il est donc difficile de donner des conseils précis ...

Pour les choses qui prennent un certain nombre de millisecondes (accès au disque, remplissant les commandes, transferts réseau, etc.) J'ai utilisé DateTime.Ticks.Now. Il semble fonctionner raisonnablement bien, et la résolution revendiquée de 10 000 000 ticks par seconde semble plutôt bonne. (Je doute que ce soit vraiment si précis, je ne sais pas de quelle facilité il est soutenu.)

Je ne connais aucun moyen d'éviter les distorsions introduites par l'exécution d'autres processus. Habituellement, je prends juste le temps moyen passé à courir chaque section qui m'intéresse, moyenné sur autant de courses que possible (pour lisser les variations causées par d'autres processus et les inexactitudes de minuterie).

(En code natif, pour le profilage de choses qui ne demandent pas de temps d'exécution, j'utilise le compteur de cycles CPU via l'instruction RDTSC, donc si vous chronométrez trop de choses pour d'autres lecture utile, mais ne finit pas si vite que la surcharge de l'appel est un problème, et que cela ne vous dérange pas d'obtenir vos lectures dans les cycles CPU plutôt que dans les unités de temps standard, ça peut valoir la peine d'écrire une petite fonction native valeur dans un UInt64 Je n'ai pas eu besoin de le faire dans le code managé moi-même si ...)

+0

Je m'attends à ce que le temps de réponse de GetValue soit typiquement de l'ordre de la nanoseconde. – Rauhotz

+0

La résolution ne prétend pas être de 10 000 000 ticks par seconde. La définition de tick est 1/10.000.000 de seconde, mais (selon MSDN) la résolution dépend de la minuterie du système - 55 millisecondes pour Windows 98, 10 millisecondes pour Windows NT (3.5 et versions ultérieures). – configurator

+0

Tout cela ne semble pas aider car il a été déclaré que l'exécution est parallèle, non? – mafu

1

Si vous essayez d'analyser les performances au lieu de commencer avec une méthode donnée obtenir un profil réel comme Profileur Ants et voir où sont les vrais goulets d'étranglement. Souvent, lorsque vous supposez que votre application n'est pas performante, vous finissez par chercher et optimiser tous les mauvais endroits et vous perdez beaucoup de temps.

+0

"Sans profileur externe". L'arbre est construit dynamiquement, donc le goulot d'étranglement peut être différent pour chaque cas d'utilisation. – Rauhotz

+0

Ce qui est bien puisque vous avez juste le profileur en cours d'exécution, puis exécutez-le de vos différentes façons et voir ce qui se passe dans le système global. La raison pour laquelle j'ai soulevé cette question est parce que essayer d'optimiser sans profilage est toujours une perte de temps. Utilisez un profileur, puis optimisez. –

+0

Donc vous pensez que je devrais dire à _customer_ d'installer un profileur qui lui indique dans quel noeud le temps est passé? – Rauhotz

Questions connexes