-1

I am attempting to see how long several functions take to execute.

The code to do this is simply

 public void GetTimeToProcess(string functionName)
        {
            // Create new stopwatch.
            Stopwatch stopwatch = new Stopwatch();

            // Begin timing.
            stopwatch.Start();

            // Do something.
            for (int i = 0; i < 1000; i++)
            {
                Thread.Sleep(1);
            }

            // Stop timing.
            stopwatch.Stop();

            // Write result.
            Console.WriteLine("Time elapsed ({1}): {0}", stopwatch.Elapsed, 
                               functionName);
        }

However, I do not want to pepper all my functions with new Stopwatch instances and the rest of this code. Rather somehow pass functions into this method or something else

What is the best way to get the execution time of several functions without copy and pasting this code into all of the functions?

nlstack01
  • 789
  • 2
  • 7
  • 30
  • You could have your method accept an `Action` or `Func`. But before you do that...Are you sure you've researched your other options? There's other profilers out there that can do this for you. I bet you'd find a lot of info if you searched for ".NET profiler" on Google. – mason Oct 22 '18 at 18:28
  • @mason Can you show me an example of Func to accomplish this? – nlstack01 Oct 22 '18 at 18:29
  • You can find samples online, for example: https://stackoverflow.com/questions/44776126/how-pass-funct-to-method-parameter. Give it a try and if you get stuck come back! – Rufus L Oct 22 '18 at 18:32
  • 2
    Use a visual studio profiler – FCin Oct 22 '18 at 18:32

2 Answers2

2

What you're doing is called profiling. And there are already a great number of profilers for .NET out there. There's no need for you to reinvent the wheel.

If you really want to you can encapsulate the logic in methods, and have those methods operate on Action's or Func<T>'s. Below is an example.

using System;
using System.Diagnostics;
using System.Threading;

namespace HelloConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            ProfileMethod(() => SomeLongRunningMethod(), nameof(SomeLongRunningMethod));
            var result = ProfileFunction(() => SomeLongRunningFunction(), nameof(SomeLongRunningFunction));

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

        public static void ProfileMethod(Action action, string methodName)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            action();
            stopwatch.Stop();
            Console.WriteLine($"Time elapsed ({stopwatch.Elapsed}): {methodName}");
        }

        public static T ProfileFunction<T>(Func<T> function, string functionName)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            var result = function();
            stopwatch.Stop();
            Console.WriteLine($"Time elapsed ({stopwatch.Elapsed}): {functionName}");
            return result;
        }

        public static void SomeLongRunningMethod()
        {
            Thread.Sleep(1000);
        }

        public static double SomeLongRunningFunction()
        {
            Thread.Sleep(1000);
            return 3.14;
        }
    }
}

You pass the operation to your profiling method as an argument. That starts the timer, performs the operation, stops the timer, and writes its output. In the case of a function, it captures the result and returns it as well.

Note I also converted your format strings to use interpolated strings, which are much preferred in most cases.

mason
  • 31,774
  • 10
  • 77
  • 121
0

unable to comment: To add on @mason's answer (which should be the accepted answer)

You can remove the nameof(..) argument in the methods because you can access the methods name through the property action.Method.Name the same applies to Func<T>

Tomek
  • 323
  • 1
  • 4
  • 19