Measure a given method's execution time - follow-up A long time ago, I've written a method that would allow me to measure the amount of time a method takes to run. I've decided to tweak this method and make use of TPL since measuring a method may take some time.

public static class ComparableUtils
{
    public static T Min&lt;T&gt;(this T t1, T t2)where T:IComparable
    {
        if (t1.CompareTo(t2) &lt;= 0)
        {
            return t1;
        }
        return t2;
    }

    public static T Max&lt;T&gt;(this T t1, T t2) where T : IComparable
    {
        if (t1.CompareTo(t2) &gt;= 0)
        {
            return t1;
        }
        return t2;
    }
}
public static class TestUtils
{
    private static readonly Stopwatch Watch = new Stopwatch();

    //This determines a minimum amount of iterations needed to perform to get a significative time measurment
    private static Task&lt;int&gt; GetIterations(Action action)
    {
        return Task.Run(() =&gt;
        {
            const int minimumTime = 20;
            int iterations = 0;
            Watch.Start();
            while (Watch.Elapsed.Milliseconds &lt; minimumTime)
            {
                action();
                ++iterations;
            }
            return iterations;
        });
    }

    private static TimeSpan MeasureTime(Action action, int iterations)
    {
        Watch.Restart();
        while (iterations-- &gt; 0)
        {
            action();
        }
        Watch.Stop();
        return Watch.Elapsed;
    }

    public static Task&lt;Time&gt; Measure(Action action, int? iterations = null, int times = 1)
    {
        return Task.FromResult(iterations)
            .ContinueWith(async t =&gt; t.Result.GetValueOrDefault(await GetIterations(action)))
            .Unwrap()
            .ContinueWith(t =&gt;
            {
                var iters = t.Result;
                TimeSpan timeTaken = TimeSpan.MaxValue;
                for (int i = 0; i &lt; times; ++i)
                {
                    timeTaken = MeasureTime(action, iters).Min(timeTaken);
                }
                return new Time(timeTaken.Ticks*100/iters);
            });
    }
}

public class Time
{
    private readonly long _nanoSeconds;
    public Time(long nanoSeconds)
    {
        _nanoSeconds = nanoSeconds;
    }

    public override string ToString()
    {
        if (_nanoSeconds &lt; 9999)
        {
            return _nanoSeconds.ToString()+"ns";
        }
        return new TimeSpan(_nanoSeconds / 100).ToString("g");
    }
}


Is this a well conducted measurement algorithm? Is there something that is amiss?
while (Watch.Elapsed.Milliseconds &lt; minimumTime)


It probably won't affect this code, but Milliseconds doesn't do what you probably think it does. I think you want TotalMilliseconds.



public static Task&lt;Time&gt; Measure(Action action, int? iterations = null, int times = 1)
{
    return Task.FromResult(iterations)
        .ContinueWith(async t =&gt; t.Result.GetValueOrDefault(await GetIterations(action)))
        .Unwrap()
        .ContinueWith(t =&gt;
        {
            var iters = t.Result;
            TimeSpan timeTaken = TimeSpan.MaxValue;
            for (int i = 0; i &lt; times; ++i)
            {
                timeTaken = MeasureTime(action, iters).Min(timeTaken);
            }
            return new Time(timeTaken.Ticks*100/iters);
        });
}



Generally speaking, if you can use await, you don't need ContinueWith().
What's the point of using Task.FromResult().ContinueWith()? Task.Run() would make much more sense here.
There is actually no reason to use Task and async-await here. You should use that only for truly asynchronous IO operations. If the caller wants to run your long-running CPU-bound code on a separate thread, they can easily do it themselves.
For performance-related code, it feels weird that you're calling GetIterations() even when it's not needed.