2012-04-11 18 views
30

Voglio vedere per quanto tempo una funzione è in esecuzione. Così ho aggiunto un oggetto di timer sulla mia forma, e sono uscito con questo codice:Come si misura la durata di una funzione?

private int counter = 0; 

// Inside button click I have: 
timer = new Timer(); 
timer.Tick += new EventHandler(timer_Tick); 
timer.Start(); 
Result result = new Result(); 
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia); 
timer.Stop(); 

E:

private void timer_Tick(object sender, EventArgs e) 
{ 
    counter++; 
    btnTabuSearch.Text = counter.ToString(); 
} 

Ma questo non conta nulla. Perché?

+0

se si imposta timer.stop(); dopo Start() è normale. Quando è necessario fermare il timer? Quando la funzione è finita? –

+3

perché non StopWatch? (http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx) – VJAI

+0

Possibile duplicato di [Misurazione del tempo di esecuzione del codice] (https://stackoverflow.com/questions/16376191/measuring- code-execution-time) –

risposta

40

per evitare problemi futuri con un timer, ecco il codice a destra:

timer = new Timer(); 
timer.Tick += new EventHandler(timer_Tick); 
timer.Interval = 1; //set interval on 1 milliseconds 
timer.Enabled = true; //start the timer 
Result result = new Result(); 
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia); 
timer.Enabled = false; //stop the timer 

private void timer_Tick(object sender, EventArgs e) 
{ 
    counter++; 
    btnTabuSearch.Text = counter.ToString(); 
} 

ma è l'aproach sbagliato. Devi utilizzare la classe Stopwatch (System.Diagnostic) perché è un timer ad alta risoluzione e la parola Diagnostica dice tutto.

Quindi provare questo:

Stopwatch timer = Stopwatch.StartNew(); 

Result result = new Result(); 
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia); 

timer.Stop(); 
TimeSpan timespan = timer.Elapsed; 

btnTabuSearch.Text = String.Format("{0:00}:{1:00}:{2:00}", timespan.Minutes, timespan.Seconds, timespan.Milliseconds/10); 
+4

Nota: con il timer impostato con un intervallo di 1 ms, è necessario fare attenzione a non pensare che il contatore sia effettivamente il numero di millisecondi. A seconda dell'hardware, l'intervallo minimo per un timer (sul mio computer) è di circa 15ms. Quindi, anche impostando l'intervallo su 1ms, verrà attivato solo ogni 15ms circa. –

+0

proverò il timer domani. Voglio solo un contatore per vedere quanto tempo è passato da quando ho premuto il pulsante. –

+1

'var timer = Stopwatch.StartNew();' <- una riga di codice in meno –

10

Il modo migliore per vedere quanto tempo impiega un po 'di codice è usare System.Diagnostics.Stopwatch.

Ecco un esempio:

using System.Diagnostics; 

#if DEBUG 
    Stopwatch timer = new Stopwatch(); 
    timer.Start(); 
#endif 

    //Long running code 

#if DEBUG 
    timer.Stop(); 
    Debug.WriteLine("Time Taken: " + timer.Elapsed.TotalMilliseconds.ToString("#,##0.00 'milliseconds'")); 
#endif 

uso il #if DEBUG per garantire il codice del cronometro non entrare nella versione di produzione, ma si poteva fare a meno.

43

Non utilizzare un timer: utilizzare la classe Stopwatch.

var sw = new Stopwatch(); 
Result result = new Result(); 

sw.Start(); 
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia); 

sw.Stop(); 

// sw.Elapsed tells you how much time passed 
+7

O anche 'var sw = Stopwatch.StartNew();' <- una riga di codice in meno –

6

per la temporizzazione di una funzione, è necessario utilizzare la Stopwatch Class

Inoltre, il motivo per il vostro timer non conta è perché non avete impostato un intervallo per esso.

7

Uso Stopwatch di System.Diagnostics:

static void Main(string[] args) 
{ 
    Stopwatch stopWatch = new Stopwatch(); 
    stopWatch.Start(); 
    Thread.Sleep(10000); 
    stopWatch.Stop(); 

    // Get the elapsed time as a TimeSpan value. 
    TimeSpan ts = stopWatch.Elapsed; 

    // Format and display the TimeSpan value. 
    string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", 
     ts.Hours, ts.Minutes, ts.Seconds, 
     ts.Milliseconds/10); 
    Console.WriteLine("RunTime " + elapsedTime); 
} 
+2

Non sarebbe più semplice stampare l'ora con 'ts.ToString (" hh: mm: ss.ff ")' o 'ts.ToString (" G ")'? – Oliver

11

si consiglia di utilizzare la classe di cronometro per le funzioni di temporizzazione.

provare quanto segue:

private int counter = 0; 

// setup stopwatch and begin timing 
var timer = System.Diagnostics.Stopwatch.StartNew(); 

Result result = new Result(); 
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia); 

// stop timer and get elapsed time 
timer.Stop(); 
var elapsed = timer.Elapsed; 

// display result time 
MessageBox.Show(elapsed.ToString("mm':'ss':'fff")); 
4

Forse, si potrebbe scrivere un metodo del genere:

public static void Time(Action action) 
{ 
    Stopwatch st = new Stopwatch(); 
    st.Start(); 
    action(); 
    st.Stop(); 
    Trace.WriteLine("Duration:" + st.Elapsed.ToString("mm\\:ss\\.ff")); 
} 

e utilizzarlo così:

Time(()=> 
{ 
CallOfTheMethodIWantToMeasure(); 
}); 
7

Visual Studio 2015 2017 Professional e L'impresa ha uno strumento diagnostico.Se si dispone di un punto di interruzione al termine della funzione, verrà visualizzato il tempo e la durata sotto la scheda Eventi come mostrato nell'immagine:

Enter image description here

si può vedere l'articolo Diagnostic Tools debugger window in Visual Studio 2015 per più dettagli.

PS; Finora solo i moduli Xamarin, il progetto multipiattaforma non supporta questa funzionalità. Mi auguro che Microsoft porti questa fantastica funzionalità anche per i progetti di moduli xamarin.

+0

da molto tempo è arrivata l'idea interessante – goodies4uall

1

Ho esaminato e concordato con tutti i suggerimenti. Ma volevo condividere una implementazione generica per il logger di esecuzione quando non vogliamo implementare la logica di Stopwatch più volte, ma vuole ancora misurare il tempo di esecuzione per più metodi.

Il motivo principale per cui non è necessario implementare il programma di registrazione in modo generico è - l'esecuzione del metodo è tra stopwatch.Start() e stopwatch.Stop() inoltre potremmo richiedere il risultato del metodo dopo l'esecuzione per un'ulteriore elaborazione.

Quindi, per risolvere questo problema, ho creato la seguente implementazione di esempio in cui il tempo di esecuzione viene registrato separatamente senza miscelarlo con il flusso del metodo effettivo.

public static class Helper 
{ 
    public static T Time<T>(Func<T> method, ILogger log) 
    { 
     var stopwatch = new Stopwatch(); 
     stopwatch.Start(); 
     var result = method(); 
     stopwatch.Stop(); 
     log.Info(string.Format("Time Taken For Execution is:{0}", stopwatch.Elapsed.TotalMilliseconds)); 
     return result; 
    } 
} 

public class Arithmatic 
{ 
    private ILogger _log; 
    public Arithmatic(ILogger log)//Inject Dependency 
    { 
     _log = log; 
    } 

    public void Calculate(int a, int b) 
    { 
     try 
     { 
      Console.WriteLine(Helper.Time(() => AddNumber(a, b), _log));//Return the result and do execution time logging 
      Console.WriteLine(Helper.Time(() => SubtractNumber(a, b), _log));//Return the result and do execution time logging 
     } 
     catch (Exception ex) 
     { 
      _log.Error(ex.Message, ex); 
     } 
    } 

    private string AddNumber(int a, int b) 
    { 
     return "Sum is:" + (a + b); 
    } 

    private string SubtractNumber(int a, int b) 
    { 
     return "Subtraction is:" + (a - b); 
    } 
} 

public class Log : ILogger 
{ 
    public void Info(string message) 
    { 
     Console.WriteLine(message); 
    } 

    public void Error(string message, Exception ex) 
    { 
     Console.WriteLine("Error Message:" + message, "Stacktrace:" + ex.StackTrace); 
    } 
} 

public interface ILogger 
{ 
    void Info(string message); 
    void Error(string message, Exception ex); 
} 

Calling Parte:

static void Main() 
{ 
    ILogger log = new Log(); 
    Arithmatic obj = new Arithmatic(log); 
    obj.Calculate(10, 3); 
    Console.ReadLine(); 
} 
+0

. Grazie per la pubblicazione. –

+0

non credi che il codice contenga troppe informazioni non correlate, credo che solo il metodo helper e il suo uso in una riga siano sufficienti – mkb

+0

Alcuni sono d'accordo ma le informazioni non sono estranee se si vuole usare questo concetto a livello più ampio/aziendale quindi deve considerare tutte queste informazioni come il logger e tutto il resto. Quindi ho appena citato modalità dettagliate di implementazione. –

-1

provare in questo modo:

this.Cursor = Cursors.WaitCursor; 

    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew(); 

    //YOUR CODE - CALL FUNCTION -- OTHER COMPUTATIONS 

    long elapsed = sw.ElapsedMilliseconds; // or sw.ElapsedTicks 

    this.Cursor = Cursors.Default; 
    lblTimeNew.Text = "Time: " + elapsed.ToString(); 

Per maggiori informazioni visitate il sito ufficiale di MSDN

https://msdn.microsoft.com/it-it/library/system.diagnostics.stopwatch(v=vs.110).aspx

1

registrare il momento in cui passo corrente inizia a elaborare

DateTime dtStart = DateTime.Now; 

//Calculate the total number of milliseconds request took (Timespan = to represent the time interval)-> current - started time stamp ... 
//TotalMilliseconds -->Gets the value of the current TimeSpan structure expressed in whole and fractional milliseconds. 
// to measure how long a function is running 
var result=((TimeSpan)(DateTime.Now - dtStart)).TotalMilliseconds.ToString("#,##0.00") + "ms"; 
Problemi correlati