freezing_
freezing_

Reputation: 1044

StopWatch returns 0ms when having two instances of watch

I am trying to measure running times of two functions, i put timers in both of them. But if I run these consecutively second returns 0ms, why is that ?

    using System;
    using System.Collections.Generic;

    namespace TestParallelLoops
    {
    class Program
    {
        static void Main(string[] args)
        {

            first();
            second();
        }

        static void first()
        {
            var watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            Console.WriteLine(fibonacci(50));

            watch.Stop();

            Console.WriteLine($"Execution Time: {watch.ElapsedMilliseconds} ms");
        }

        static void second()
        {
            var watch1 = new System.Diagnostics.Stopwatch();

            watch1.Start();

            Console.WriteLine(fibonacciRecursive(50));

            watch1.Stop();

            Console.WriteLine($"Execution Time: {watch1.ElapsedMilliseconds} ms");
        }

        static long fibonacci(int n)
        {
            Dictionary<int, long> last = new Dictionary<int, long>();

            last[0] = 0;
            last[1] = 1;
            int next = 2;

            while (next<=n)
            {
                last[next] = last[next-1] + last[next-2];
                next++;
            }

            return last[n];
        }

        static long fibonacciRecursive (int n)
        {
            if (n == 0) return 1;
            if (n == 1) return 1;

            return fibonacciRecursive(n - 1) + fibonacci(n - 2);
        }


    }
}

If i execute only first i see ~100 ms if i execute only second i see ~100ms but if i execute both i see ~100 ms and 0ms.

Many thanks

Upvotes: 1

Views: 360

Answers (2)

Dustin S.
Dustin S.

Reputation: 46

I think your 100ms is probably the time it takes to unblock the console. Save the value off and write the console outside of your timed block like this (do same for first() method):

    static void second()
    {
        var watch1 = new System.Diagnostics.Stopwatch();
        watch1.Start();
        var a = fibonacciRecursive(50);
        watch1.Stop();
        Console.WriteLine(a);
        Console.WriteLine($"Execution Time: {watch1.ElapsedMilliseconds} ms");
    }

Upvotes: 2

Jonathon Chase
Jonathon Chase

Reputation: 9704

Dustin S. is likely on the money with the first Console.WriteLine causing the initial 100ms hit. Changing up main to

static void Main(string[] args)
{
    Console.WriteLine("Here we go!");
    first();
    second();
}

Tends to yield results of 0 ms for both, given how fast the machine running it is, and whatever the underlying precision of the StopWatch is.

Your fibanacciResursive call isn't full recursive, it should likely have the following return:

return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2);

Which takes ~2s (I'd lowered the value to 45) longer than I'd like to wait to evaluate for a value of 50 on my machine, since this isn't caching intermediary results and duplicates a lot of effort.

The recusive implementation you have does have another issue with the guards that is causing it to actually return the n + 1th fibonacci number, but I'll leave that as an exercise.

In any case, given the current implementation of fibonacci and fibonacciRecursive (without the fix mentioned above), a 0ms result for both with a value as small as 50 sounds right for most machines.

Upvotes: 3

Related Questions