2013-08-08 14 views
9

Ho un codice breve che esegue diverse operazioni e voglio misurare il tempo necessario per eseguire ciascuna. Ho letto qui sulla lezione di cronometro e volevo ottimizzare le mie misurazioni del tempo. mie funzioni chiamate 5 altre funzioni e voglio misurare ogni senza dichiarare:Come utilizzare StopWatch più volte in C#?

stopwatch sw1 = new stopwatch(); 
stopwatch sw2 = new stopwatch(); 
etc.. 

mia funzione sembra che:

public bool func() 
{ 
.... 
func1() 
func2() 
.... 
.... 
func5() 
} 

c'è un modo per misurare il tempo utilizzando una sola istanza cronometro?

grazie !!

risposta

17

Usa delegati di passare un metodo come parametro per una funzione.

Qui ho utilizzato i delegati di azioni poiché i metodi specificati non restituiscono un valore.

È possibile modificare di conseguenza se il metodo ha un tipo di ritorno o parametro utilizzando un delegato funzione

static void Main(string[] args) 
    { 
     Console.WriteLine("Method 1 Time Elapsed (ms): {0}", TimeMethod(Method1)); 
     Console.WriteLine("Method 2 Time Elapsed (ms): {0}", TimeMethod(Method2)); 
    } 

    static long TimeMethod(Action methodToTime) 
    { 
     Stopwatch stopwatch = new Stopwatch(); 
     stopwatch.Start(); 
     methodToTime(); 
     stopwatch.Stop(); 
     return stopwatch.ElapsedMilliseconds; 
    } 

    static void Method1() 
    { 
     for (int i = 0; i < 100000; i++) 
     { 
      for (int j = 0; j < 1000; j++) 
      { 
      } 
     } 
    } 

    static void Method2() 
    { 
     for (int i = 0; i < 5000; i++) 
     { 
     } 
    } 
} 

Utilizzando questo si potrebbe passare qualsiasi metodo che si desidera.

Spero che questo aiuti!

4

Sì, provate questo:

void func1() 
    { 
     Stopwatch sw = new Stopwatch(); 
     sw.Start(); 
     func1(); 
     sw.Stop(); 
     Console.Write(sw.Elapsed); 

     sw.Restart(); 
     func2(); 
     sw.Stop(); 
     Console.Write(sw.Elapsed); 
    } 
+0

grazie mille !!! – user1386966

+0

C'è qualche differenza tra scrivere sw.Restart e sw.Avviare in questo caso? – user1386966

+2

Utilizzare Riavvia per interrompere la misurazione dell'intervallo corrente e avviare una nuova misurazione dell'intervallo (MSDN). Il riavvio cancella il tempo trascorso. – oakio

4

Quello che vi serve è il funzione di Riavvio del classe cronometro, qualcosa di simile:

public bool func() 
{ 
    var stopwatch = Stopwatch.StartNew(); 

    func1(); 

    Debug.WriteLine(stopwatch.ElapsedMilliseconds); 

    stopwatch.Restart(); 

    func5(); 

    Debug.WriteLine(stopwatch.ElapsedMilliseconds); 
} 
1

È possibile utilizzare questo piccolo classe:

public class PolyStopwatch 
{ 
    readonly Dictionary<string, long> counters; 

    readonly Stopwatch stopwatch; 

    string currentLabel; 

    public PolyStopwatch() 
    { 
     stopwatch = new Stopwatch(); 
     counters = new Dictionary<string, long>(); 
    } 

    public void Start(string label) 
    { 
     if (currentLabel != null) Stop(); 

     currentLabel = label; 
     if (!counters.ContainsKey(label)) 
      counters.Add(label, 0); 
     stopwatch.Restart(); 
    } 

    public void Stop() 
    { 
     if (currentLabel == null) 
      throw new InvalidOperationException("No counter started"); 

     stopwatch.Stop(); 
     counters[currentLabel] += stopwatch.ElapsedMilliseconds; 
     currentLabel = null; 
    } 

    public void Print() 
    { 
     if (currentLabel != null) Stop(); 

     long totalTime = counters.Values.Sum(); 
     foreach (KeyValuePair<string, long> kvp in counters) 
      Debug.Print("{0,-40}: {1,8:N0} ms ({2:P})", kvp.Key, kvp.Value, (double) kvp.Value/totalTime); 
     Debug.WriteLine(new string('-', 62)); 
     Debug.Print("{0,-40}: {1,8:N0} ms", "Total time", totalTime); 
    } 
} 

usare in questo modo:

var ps = new PolyStopwatch(); 

ps.Start("Method1"); 
Method1(); 
ps.Stop(); 

// other code... 

ps.Start("Method2"); 
Method2(); 
ps.Stop(); 

ps.Print(); 

Se le chiamate si susseguono, è possibile omettere Stop()

ps.Start("Method1"); 
Method1(); 
ps.Start("Method2"); 
Method2(); 
ps.Print(); 

Funziona bene con un ciclo:

for(int i = 0; i < 10000; i++) 
{ 
    ps.Start("Method1"); 
    Method1(); 
    ps.Start("Method2"); 
    Method2(); 
} 
ps.Print();