Modello di progettazione corretto per utilizzare la classe StopWatch

2

Devo misurare il tempo di esecuzione per un blocco di codice. Ho implementato la semplice classe StopWatch come link . Se invocherò i metodi della classe StopWatch direttamente tra la logica aziendale, il mio codice sorgente diventerà illeggibile e impuro.

Quale modello di progettazione può essere utile nella mia situazione per mantenere il codice leggibile e pulito?

    
posta coms 13.02.2012 - 17:36
fonte

2 risposte

5

Se stai misurando i metodi, questo è un classico esempio di preoccupazioni trasversali che AOP è progettato per risolvere.

Il mio Java è debole, ma qualcosa del genere in C # usando PostSharp funzionerebbe ...

Crea una classe ProfileAttribute che esegue la profilatura e la registra in qualche file di log / database / qualunque sia

public sealed class ProfileAttribute : Attribute
{
    private StopWatch stopWatch;

    public override OnEntry(MethodExecutionArgs args)
    {
        this.stopWatch = new StopWatch();
        this.stopWatch.Start();
    }

    public override OnExit(MethodExecutionArgs args)
    {
        this.stopWatch.Stop();
        /* 
        log(string.Format("[{0}]{1}.{2} took {3}ms", 
            DateTime.Now, 
            args.ClassName, // may not be actual member name, I forget
            args.MethodName, // may not be actual member name, I forget
            stopWatch.Elapsed.TotalMilliseconds));
        */
    }
}

Quindi, puoi attribuire qualsiasi metodo che vuoi profilare (senza dover ingombrare troppo il codice) semplicemente applicando l'attributo in questo modo:

[Profile]
public void WatchedMethod()
{
    /* Code */
}

In seguito, puoi controllare il tuo log (s) e dovrebbe vedere qualcosa come:

[Jan 1, 2012 00:00:01]MyClass.WatchedMethod took 1.001ms

[Jan 1, 2012 00:00:02]MyClass.WatchedMethod took 1.000ms

[Jan 1, 2012 00:00:03]MyClass.WatchedMethod took 1.002ms

edita

A quel punto ... ha senso scrivere una piccola utility in grado di estrarre i dati dai log, filtrarli e presentarli in modo tale da renderli utilizzabili (media dei tempi di esecuzione, mostrare i tempi anomali, ecc.)

Si noti inoltre che l'utilizzo di alcuni framework AOP (forse AspectJ ... non è sicuro) consente anche di decidere su quale build (i) alcuni aspetti possono essere incorporati ... cioè. puoi tessere questo attributo di profilo nella build di debug, ma non inserirlo nella build di rilascio.

Nota sulle prestazioni di runtime:

Se il tuo tessitore è un tessitore in fase di compilazione, inietterà il codice dell'aspetto nel codice durante la compilazione. Usando PostSharp con l'esempio fornito, il codice risultante sarà:

private StopWatch stopWatch;

public void WatchedMethod()
{
    this.stopWatch = new StopWatch();
    this.stopWatch.Start();

    /* Code */

    this.stopWatch.Stop();
    /* 
    log(string.Format("[{0}]{1}.{2} took {3}ms", 
        DateTime.Now, 
        args.ClassName, // may not be actual member name, I forget
        args.MethodName, // may not be actual member name, I forget
        stopWatch.Elapsed.TotalMilliseconds));
    */
}
    
risposta data 13.02.2012 - 19:23
fonte
1

La misurazione del tempo di esecuzione è qualcosa che non è un'aggiunta permanente al tuo codice, è una cosa temporanea ai fini del test. Non è un grosso problema se il tuo codice sembra scadente mentre stai testando questo, è come aggiungere codice per il debug. Dovrebbe essere gettato dove è necessario, i risultati dovrebbero essere registrati e il codice rimosso. Renderlo bello è una perdita di tempo.

Se è necessario visualizzare il tempo di esecuzione per gli utenti, quindi la sua parte della logica dei programmi e deve essere implementato direttamente come parte della logica di tracciamento. Dovrebbe avere un effetto minimo sulla leggibilità del tuo codice se hai progettato correttamente la classe del cronometro stesso. Dovrebbero esserci più di circa 4 righe aggiunte a qualsiasi area che stai misurando, (dichiarare / inizializzare, avviare, fermare, ottenere tempo) e dovrebbe avere un impatto minimo a meno che il tuo codice esistente non sia già strutturato in modo scadente, che è un problema separato .

    
risposta data 13.02.2012 - 17:51
fonte

Leggi altre domande sui tag