views:

82

answers:

2

I am new to C# world. I am attempting to calculate time taken by a algorithum for the purpose of comparison. Following code measures the elapsed time from when a subroutine is called until the subroutine returns to the main program.This example is taken from "Data structures through C#" by Michael McMillan. After running this program the output is Time=0, which is incorrect. The program appears to be logically correct. Can anybody help me. Following is the code

 using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Chap1
{
    class chap1
    {
        static void Main()
        {
            int[] nums = new int[100000];
            BuildArray(nums);
            Timing tObj = new Timing();
            tObj.startTime();
            DisplayNums(nums);
            tObj.stopTime();
            Console.WriteLine("Time: " + tObj.result().TotalSeconds);
            Console.WriteLine("Start Time: " + tObj.startTime().TotalSeconds);
            Console.WriteLine("Duration : " + tObj.result().TotalSeconds);
            Console.ReadKey();
        }
        static void BuildArray(int[] arr)
        {
            for (int i = 0; i <= 99999; i++)
                arr[i] = i;
        }
        static void DisplayNums(int[] arr)
        {
            for (int i = 0; i <= arr.GetUpperBound(0); i++)
                Console.WriteLine(arr[i]);
        }
    }
class Timing
    {
        TimeSpan StartTiming;
        TimeSpan duration;
        public Timing()
        {
            StartTiming = new TimeSpan(0);
            duration = new TimeSpan(0);
        }
        public TimeSpan startTime()
        {
            GC.Collect();


     GC.WaitForPendingFinalizers();
            StartTiming = Process.GetCurrentProcess().Threads[0].UserProcessorTime;
            return StartTiming;
        }
        public void stopTime()
        {
            duration = Process.GetCurrentProcess().Threads[0].UserProcessorTime.Subtract(StartTiming);

        }
        public TimeSpan result()
        {
            return duration;
        }
    }
}
+2  A: 

You don't use the Timing class anywhere in your main function and I don't see where you print the time either. Is this the EXACT code you're running?

Update per new code:

Don't run it in debug mode... build your release version and then run the executable manually: http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/3f10a46a-ba03-4f5a-9d1f-272a348d660c/

I tested your code and it worked fine when running the release version, but when I was running it in the debugger it was not working properly.

Lirik
Sorry for posting incorrect code. Now I have posted exact code
Rajiv Yelkawar
Because most of the time is spent doing console output -- i.e. a kernel WriteFile(CONOUT$) call, which is not included in "user" time.
Ben Voigt
@Ben I found this article suggesting that running the code in Debug mode would not show the time: http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/3f10a46a-ba03-4f5a-9d1f-272a348d660c/
Lirik
The thread 0 assumption is only one of several things very broken about that code. But why anyone would try to measure performance with a debugger attached is beyond me, the .NET JIT detects the debugger and generates very different code to assist in debugging, any timing measurements made in the debugger are USELESS.
Ben Voigt
@Ben I don't see how else he would have gotten Time = 0, I tested his code and it worked just fine in Release mode...
Lirik
+1  A: 

The Stopwatch class is designed for this.

UserProcessorTime doesn't begin to have the resolution necessary to measure counting to 100000 in a for loop. Your WriteLine calls won't be included in user time as they are I/O time. Your code might not be running on thread 0. User time isn't updated except at context switches. When you print startTime, you're changing the stored value. There are probably some other things that can go wrong I haven't thought of.

I strongly suggest you use the Stopwatch class which takes advantage of the CPU's performance counters.

Ben Voigt
@Ben the OP is asking why this example is not working.
Lirik
Dear Ben, I will appricate if you could refer to the correct code which I have edited just now. Thanks
Rajiv Yelkawar
In the .NET environment, every program runs inside application domain. This allows the operating system to separate different program running on it at the same time. Within a process, aprogram or a part of a program is run inside a thread. Execution time for a program is allocated by the operating system via threads. When we are timing the code for a program, we want to make sure that we’re timing just the code inside the process allocated for our program and not other tasks being performed by the operating system. Using stopwatch class we would be including other time in the total time.
Rajiv Yelkawar
Then why did you say you wanted "elapsed time"? Anyway, you can turn up the thread priority to avoid having other processes interrupt your time measurement. And I assure you that I already know about threads, processes, app domains, and scheduling. The trouble with ProcessorUserTime (and the underlying Win32 API GetThreadTimes) is that they have a systematic error if your thread never uses the entire quantum in user mode (in your case it always does a synchronous I/O call).
Ben Voigt