How to use StopWatch multiple times in C#?

29,758

Solution 1

Use delegates to pass a method as a parameter to a function.

Here I used Action Delegates as the methods specified does not return a value.

You can modify it accordingly if your method has a return type or parameter by using a Function delegate

    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++)
        {
        }
    }
}

By using this you could pass any method you want.

Hope that helps!

Solution 2

What you need is the Restart function of the Stopwatch class, something like this:

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

    func1();

    Debug.WriteLine(stopwatch.ElapsedMilliseconds);

    stopwatch.Restart();

    func5();

    Debug.WriteLine(stopwatch.ElapsedMilliseconds);
}

Solution 3

Yes, try this:

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

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

Solution 4

You can use this little class:

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);
    }
}

Use it like this:

var ps = new PolyStopwatch();

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

// other code...

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

ps.Print();

If calls follow each other, you can omit the Stop()

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

It works well with a loop:

for(int i = 0; i < 10000; i++)
{
    ps.Start("Method1");
    Method1();
    ps.Start("Method2");
    Method2();
}
ps.Print();
Share:
29,758
user1386966
Author by

user1386966

Updated on July 09, 2022

Comments

  • user1386966
    user1386966 almost 2 years

    I have short code that performs different operations and I want to measure the time that takes to perform each. I read here about Stopwatch class, and wanted to optimize my time measurements. my functions calls 5 other functions and I want to measure each without declaring :

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

    my function looks like that:

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

    is there any way to measure the time using one stopwatch instance?

    thanks!!