Click here to Skip to main content
15,868,141 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
Now a days I'm practicing some programs of C#. I have an issue in this program.

I have created this program and it took 21 seconds to execute and my CPU usage is 20% and Ram usage is 1Gb max.

C#
static void Main(string[] args)
        {
            string str = Console.ReadLine();

            if (str == "start")
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                for (int i = 1; i < 200000; i++)
                {
                   

                    Console.WriteLine("Acccessed Value" + i.ToString());
                    Console.WriteLine("Time " + sw.ElapsedMilliseconds);

                }
            }
            Console.Read();
        }


but when I create 2 instances of this It took 140 seconds and CPU usage is 20 % and Ram usage is 1GB max.

Can you please help me, how can I run multiple instances which will take 21 seconds but can utilize my Ram and CPU as maximum.

What I have tried:

C#
static void Main(string[] args)
        {
            string str = Console.ReadLine();

            if (str == "start")
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                for (int i = 1; i < 200000; i++)
                {
                    

                    Console.WriteLine("Acccessed Value" + i.ToString());
                    Console.WriteLine("Time " + sw.ElapsedMilliseconds);

                }
            }
            Console.Read();
        }
Posted
Updated 11-Jan-17 3:14am
v2
Comments
Tomas Takac 11-Jan-17 2:14am    
How exactly did you run the "2 instances" test and how did you measure those 140 seconds?
Sachin k Rajput 11-Jan-17 2:15am    
I run two instances by using "Debug"- start as new instance and the time is printing in stopwatch.
Richard MacCutchan 11-Jan-17 3:48am    
Running any code in Debug will take much longer than normal. and since Windows is not a real time OS most timings cannot be used to measure performance.
StM0n 11-Jan-17 2:53am    
Could you just start them in two console windows... just curious...
Sachin k Rajput 11-Jan-17 3:46am    
tried but no luck..

I tried it mostly your way and it took 39 seconds. Granted, I don't know the contents of your Stopwatch class, but all mine does is return a TimeSpan when I call my ElapsedTime method. I'm also making only one call to Console.Writeline with a string.Concatendated value.

C#
public class StopWatch
{
    public DateTime StartTime { get; set; }

    public void Start()
    {
        this.StartTime = DateTime.Now;
    }

    public TimeSpan ElapsedTime()
    {
        return (DateTime.Now - this.StartTime);
    }
}

C#
static void Main(string[] args)
{
    string str = Console.ReadLine();

    if (str == "start")
    {
        StopWatch sw = new StopWatch();
        sw.Start();
        for (int i = 1; i < 200000; i++)
        {
            Console.WriteLine(string.Concat("Acccessed Value: ", i.ToString(), ", Time: ", sw.ElapsedTime().ToString()));
        }
    }
    Console.Read();
}
 
Share this answer
 
v2
Comments
F-ES Sitecore 11-Jan-17 9:27am    
Stopwatch is a part of the .net framework, it's in System.Diagnostics
Out of curiosity, I tried a multi-threaded approach running a single app. This too 47 seconds.

C#
static void Main(string[] args)
{
    string str = Console.ReadLine();

    if (str == "start")
    {
        StopWatch sw = new StopWatch();
        sw.Start();
        Parallel.Invoke(()=>
        {
            for (int i = 1; i < 200000; i++)
            {
                Console.WriteLine(string.Concat("Thread 1, Acccessed Value: ", i.ToString(), ", Time: ", sw.ElapsedTime().ToString()));
            }
        },
        ()=>
        {
            for (int i = 1; i < 200000; i++)
            {
                Console.WriteLine(string.Concat("Thread 2, Acccessed Value: ", i.ToString(), ", Time: ", sw.ElapsedTime().ToString()));
            }
        });
    }
    Console.Read();
}
 
Share this answer
 
And finally, I wondered if sharing the same stopwatch might be causing some sort of self-induced delays, so I did this, which resulted in about 49 seconds of elapsed timed.

C#
static void Main(string[] args)
{
    string str = Console.ReadLine();

    if (str == "start")
    {
        StopWatch sw = new StopWatch();
        sw.Start();
        Parallel.Invoke(()=>RunTask(1), ()=>RunTask(2));
    }
    Console.Read();
}

private static void RunTask(int taskno)
{
    StopWatch sw = new StopWatch();
    sw.Start();
    string taskNumber = taskno.ToString();
    for (int i = 1; i < 200000; i++)
    {
        Console.WriteLine(string.Concat("Thread ", taskNumber," , Acccessed Value: ", i.ToString(), ", Time: ", sw.ElapsedTime().ToString()));
    }
}
 
Share this answer
 
Comments
Sachin k Rajput 11-Jan-17 8:23am    
Thanks for your suggestions, but you can notice that single thread is taking 21 seconds but two threads takes 42+ seconds.I have tried these approaches but unable to bring it to 20+ sec.
Dave Kreskowiak 11-Jan-17 8:39am    
What hardware are you running this on? CPU, motherboard, video card, ...
#realJSOP 11-Jan-17 9:10am    
You're not going to get two apps that write to the console 200k times to finish in 21 seconds. I got it down to 0.002 seconds only writing to the console one time at the end of the loop. That is your best option if you're looking for performance. In short, stop dickin' around with the console.
F-ES Sitecore 11-Jan-17 9:26am    
You realise that a CPU can only do one thing at a time? If it takes 20 seconds to do one task then doing two of those tasks at the same time is going to take over 40 seconds....20 seconds for each task and then time on top every time the thread needs switched in and out of context. Multi-threading will only makes things faster if the code can run on separate CPUs or cores, and that level of processing is dictated by the OS, it decides where your code runs, that's its job.

http://stackoverflow.com/questions/32343/how-do-i-spawn-threads-on-different-cpu-cores
Dave Kreskowiak 11-Jan-17 10:12am    
There's a ton of factors that affects the execution of your app. Some of which have already been mentioned.

Additionally, Windows gives the currently active (focused) application more priority over background applications. Your background instance will run slower than the foreground instance.

Consoles have screen buffers, which you can resize to be quite large. The larger the buffer, the more data has to be moved around for each line that gets added to the console. I keep my console windows at 120 columns wide by 5000 lines deep. On my current machine (2 cores, hyperthreaded), a single instance of your app takes 25 seconds to run. Two instances takes about 140 seconds.

There's nothing you can do to change this. Console access is just ... slow.

I don't know what you're expecting or what you think the problem is. What you're seeing is normal.
My final solution - execution time is 0.002 seconds (I would call that "negligible" as far as elapsed time is concerned):
C#
static void Main(string[] args)
{
    string str = Console.ReadLine().ToLower();

    if (str.Contains("start"))
    {
        StopWatch sw = new StopWatch();
        sw.Start();
        if (str.EndsWith("p"))
        {
            Parallel.Invoke(()=>RunTask(1), ()=>RunTask(2));
        }
        else
        {
            RunTask();
        }
    }
    Console.Read();
}

private static void RunTask(int taskno=0)
{
    StopWatch sw = new StopWatch();
    sw.Start();
    string taskNumber = taskno.ToString();
    for (int i = 1; i < 200000; i++)
    {
    }
    Console.WriteLine(string.Concat("Thread ", taskNumber," , Elapsed: ", sw.ElapsedTime().ToString()));
}

Put that in your pipe and smoke it.

BTW, if you insist on the task taking 21 seconds, simply put Thread.Sleep(21000) at the end of Main().
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900