i'm running this code:
public static void func(int i)
{
Console.WriteLine(i);
func(i + 1);
}
static void Main(string[] args)
{
func(0);
}
obviously it causes StackOverflowException, but something weird happens: From i = 0 to i = 10,000 it runs pretty slow, (about 13 seconds on my computer, using visual studio 2015) but from 10,000 to 20,000 it's almost immediately (about 1 second). Why is why is it happening?
Thanks.
Did you define the buffer size of your console window to be 10,000 lines? The WriteLine is the slowest part in your code. The console window seems to be faster once it reached the maximum number of lines.
I ran this piece of code in tutorialspoint's online c# compiler:
using System.IO;
using System;
using System.Diagnostics;
class Program
{
static Stopwatch stopwatch = new Stopwatch();
static TextWriter tw = new StreamWriter("Result.txt");
public static void func(int i)
{
if (i > 40000)
return;
tw.WriteLine(stopwatch.ElapsedMilliseconds + " " + i);
tw.Flush();
func(i + 1);
}
static void Main(string[] args)
{
stopwatch.Start();
func(0);
stopwatch.Stop();
tw.Close();
}
}
The result I got is the this
As you can see there are a few jumps in the time, specifically at 20461 and 20548. I don't know what to make of this though...
Maybe there is something about the Visual Studio configuration or something specific to your machine. When I run your code in release config it gets executed within 3 milliseconds. In debug mode the "i" never passes 9000 ...
class Program
{
public static void func(int i)
{
if (i % 1000 == 0)
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss:ff") + " => i : " + i.ToString());
func(i + 1);
}
static void Main(string[] args)
{
func(0);
Console.Read();
}
}
Related
I'm learning async in C# and want to show a program runtime every three seconds. I have two solutions, but neither works completely properly.
Solution 1
In the first solution, I have a loop where I call two methods. The first performs the calculation and the second shows the startup time, which is divisible by 3.
namespace Async
{
class Program
{
static void Main(string[] args)
{
PerformLoop();
Console.ReadLine();
}
public static async void PerformLoop()
{
Stopwatch timer = new Stopwatch();
timer.Start();
List<Task> l = new List<Task>();
for (int i = 0; i < 50; i++)
{
l.Add(AsyncCalculation(i));
l.Add(ShowTime(Convert.ToInt32(timer.Elapsed.TotalMilliseconds)));
}
await Task.WhenAll(l);
timer.Stop();
Console.WriteLine("Total execution time: " +
timer.Elapsed.TotalMilliseconds);
}
public async static Task AsyncCalculation(int i)
{
var result = 10 * i;
Console.WriteLine("Calculation result: " + result);
}
public async static Task ShowTime(int execTime)
{
if (execTime % 3 == 0)
{
Console.WriteLine("Execution time: " + execTime);
}
}
}
}
Solution 2
In the second solution, I call two methods in a loop. The first performs calculations and the second displays the operation time after 3 seconds. Unfortunately, in this case, the second method blocks the execution of the first.
namespace Async
{
class Program
{
static void Main(string[] args)
{
CallMethod();
Console.ReadLine();
}
public static async void CallMethod()
{
for (int i = 0; i < 50; i++)
{
var results = Calculation(i);
var calcResult = results.Item1;
var time = results.Item2;
ShowResult(calcResult);
await ShowDelayTime(time);
}
}
public static void ShowResult(int calcResult)
{
Console.WriteLine("Calculation result: " + calcResult);
}
public async static Task ShowDelayTime(int execTime)
{
await Task.Delay(3000);
Console.WriteLine("Execution time: " + execTime);
}
public static Tuple<int, int> Calculation(int i)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var result = 10 * i;
stopwatch.Stop();
return Tuple.Create(result,
Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds));
}
}
}
I have no idea how to continuously display the calculation results and show the running time of the program by three seconds :(((
Edit
Expected output (example):
Calculation result: 0
Calculation result: 10
Execution time: 3 seconds
Calculation result: 20
Calculation result: 30
Calculation result: 40
Execution time: 6 seconds
Calcultion result: 50
//Next iterations
The program now shows the result, waits three seconds, and then go to next iteration. I want iterations for calculations to show regardless (independently) of time. I want the time to show every three seconds of the program running.
You could use a System.Threading.Timer in order to invoke a callback every 3 seconds, and a Stopwatch in order to measure the elapsed seconds since the start of the program:
var stopwatch = Stopwatch.StartNew();
var timer = new System.Threading.Timer(_ =>
{
Console.WriteLine($"Execution time: {stopwatch.Elapsed.TotalSeconds:#,0} seconds");
}, null, 3000, 3000);
I would like to know if there is any difference in the performance by doing the following:
void Example(string message)
{
System.Console.WriteLine(message);
}
or
void Example(string message)
{
ConsoleMessage(message);
}
void ConsoleMessage(string message) => System.Console.WriteLine(message);
You can check how it compiles on this website - SharpLab. As you can see
void ConsoleMessage(string message) => System.Console.WriteLine(message);
is compiled to another method. The only difference is one more method call when using Example2. You can read more about cost of method calls in this post - How expensive are method calls in .net
It's very, very unlikely to be your bottleneck though. As always, write the most readable code you can first, and then benchmark it to see whether it performs well enough. If it doesn't, use a profiler to find the hotspots which may be worth micro-optimising.
I wrote that
static void ConsoleMessage(string message) => Console.WriteLine(message);
static void ExampleIndirect(string message)
{
ConsoleMessage(message);
}
static void ExampleDirect(string message)
{
Console.WriteLine(message);
}
By using JustDecompile on the release exe, I found that :
private static void ConsoleMessage(string message)
{
Console.WriteLine(message);
}
private static void ExampleDirect(string message)
{
Console.WriteLine(message);
}
private static void ExampleIndirect(string message)
{
Program.ConsoleMessage(message);
}
So I'm not so sure that it "is compiled to another method".
However, the difference seems not to be noticeable on benchmarks.
EDIT :
Results of my benchmark :
Iterations / Direct Time (ms) / Indirect time (ms)
10 1 0
5000 154 148
50000 1514 1502
100000 3025 3019
500000 15191 15150
1000000 30362 30276
And the code :
static void Loop(int times)
{
Stopwatch sw = Stopwatch.StartNew();
writer.Write(times.ToString() + "\t");
for (int i = 0; i < times; i++)
ExampleDirect("Test " + i.ToString());
writer.Write(sw.ElapsedMilliseconds.ToString() + "\t");
sw.Restart();
for (int i = 0; i < times; i++)
ExampleIndirect("Test " + i.ToString());
writer.Write(sw.ElapsedMilliseconds.ToString() + Environment.NewLine);
}
I have a scenario to monitor the state of the ui test. If the test is running more than 30 mins, stop the test run and start with another test. Here is the code developed to simulate the same. I apologies if i am duplicating here.
Reference: execute mutiple object methods parallel
Here is the sample program that, developed in line with my requirement.I request experts to comment on my approach and suggest me the best of it.
<code>
namespace ParallelTasksExample
{
internal class Program
{
private static Stopwatch testMonitor;
private static int timeElapsed;
private static void Main(string[] args)
{
Parallel.Invoke(() => PrintNumber(), () => MonitorSequence());
}
private static void PrintNumber()
{
testMonitor = new Stopwatch();
testMonitor.Start();
for (int i = 0; i <= 10; i++)
{
System.Threading.Thread.Sleep(5000);
timeElapsed = testMonitor.Elapsed.Seconds;
Console.WriteLine("Running since :" + timeElapsed + " seconds");
}
}
private static void MonitorSequence()
{
while (timeElapsed < 25)
{
System.Threading.Thread.Sleep(2000);
Console.WriteLine("Time Elapsed :" + timeElapsed + " seconds");
}
testMonitor.Stop();
testMonitor.Reset();
Console.WriteLine("Test has taken more then 25 seconds. Closing the current test sequence initiated.");
}
}
}
</code>
I am facing an issue, when the actual code developed based on the above example.
task 1 is completed and task 2 is in progress. Meanwhile task 1 is waiting for task2 to finish. How can we make both tasks are independent?
I've written a parellel.foreach, but the last iteration allways waits for execution before all other items have been processed, in this case, number 10 fires only when 1-9 are ready, tried it a couple of times, why is that and can i fix that?
here is my code:
class Program
{
public static void Main(string[] args)
{
int Min = 100;
int Max = 200;
Random randNum = new Random();
int[] test2 = Enumerable.Repeat(0, 10).Select(i => randNum.Next(Min, Max)).ToArray();
string[] result = test2.Select(x => x.ToString()).ToArray();
int count = 0;
var options = new ParallelOptions { MaxDegreeOfParallelism = 4 };
Parallel.ForEach(result, options, rec =>
{
count++;
go(count);
});
Console.WriteLine("Ready!");
Console.ReadKey();
}
public static void go(int counter)
{
Console.WriteLine("START: " + counter.ToString());
Thread.Sleep(3500);
Console.WriteLine("END: " + counter.ToString());
}
}
EDIT
I ran the program for 20-30 times and it seems that a few times 10 is started before 9 ended. I think this happens in about 4 or 5 percent of the times. It's (working properly) happening some sort of random. because it works sometimes it feels a bit buggy, but not a big issue for the performance of my application which i'm building. You understand the above was a testcase, not a part of the actual project :)
i wanted to create a program like this .
For every minute the time should be printed in the format of
h:m .For every 5 min it should print "break" this should continue for 24 hours ..
like this
0:0
0:1
0:2
0:3
0:4
break
0:6
0:7
0:8
0:9
break
0:11
.
.
.
23:59
i came with a program that solves it ..but i never used DateTime or any time function , i just used Thread.Sleep to dalay printing for 1 minute every time ...
i wanted to use some other method other than Thread.Sleep to solve it ...
so please guide me .. (sorry for my Bad english)
this is how i did with Thread.Sleep .
please provide me with any other solutions
using System;
using System.Threading;
class try22
{
public static void Main()
{
for(int i=0;i<24;i++)
{
for(int j=0;j<60;j++)
{
if(j%5 != 0 || (j == 0 && i == 0))
{
Thread.Sleep(20);
Console.WriteLine(i+":"+j);
}
else if(j%5 == 0 )
{
Thread.Sleep(20);
Console.WriteLine("break");
}
}
}
}
}
thanks guys i came up with the solution of using actual dates instead of array numbers in my problem
im getting weird errors with timer .. :( so i used thread.sleep itslef
using System;
using System.Threading;
class try22
{
public static void Main()
{
DateTime dt1 = new DateTime();
dt1 = DateTime.ParseExact("0:0", "H:m",null);
int cford=dt1.Day+1;
for (; dt1.Day!=cford; )
{
dt1 = addm(dt1);
Console.WriteLine(dts(dt1));
Thread.Sleep(60000);
}
}
public static string dts(DateTime dt)
{
string tmp = dt.ToString("H:m");
if (dt.Minute % 5 == 0)
return "BREAK";
else
return tmp;
}
public static DateTime addm(DateTime dt)
{
return dt.AddMinutes(1);
}
}
Which of these were you asked for?
Show the current time once per minute
Show the current time at the start of every minute like an alarm
Assuming 1, here's a couple of hints in the right direction (which should be helpful either way):
You can get the current date and time as a DateTime object using DateTime.Now
DateTime objects can return custom string output using .ToString("format").
Format is specified with a custom date and time format string. For example, to get the current hour in 24-hour time (without leading zeroes) you could use DateTime.Now.ToString("H").
As per the reference, you can include a string literal (unprocessed string) in your format. For example DateTime.Now.ToString("'Hour is: 'H") would return Hour is: 6
You can get the "minute" value of a DateTime object as an int using .Minute. For example, int minute = DateTime.Now.Minute;
If you want some code to run periodically, one way is to move it into its own method then setup a System.Threading.Timer like this:
void SomeMethod(object state) { /* DO STUFF HERE */ }
// Initialise the timer in your main() method
// As per MSDN for System.Threading.Timer, first number (0) is start delay.
// Second number (60000) is interval in milliseconds (60 seconds)
// This will cause SomeMethod to be called once every 60 seconds starting now.
Timer timer = new Timer(new TimerCallback(SomeMethod), null, 0, 60000);
You will need to stop your application exiting straight away after making the Timer (otherwise it will never get to run). One easy way to do this in a command line application is place a Console.Read() at the end of your Main() method which will wait for user input.
I have used Timer instead of Thread
class Program
{
private static System.Timers.Timer aTimer;
static int j = 0;
static int i = 0;
public static void Main()
{
// Create a timer with a Minute interval.
aTimer = new System.Timers.Timer(60000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 1 Minute (60000 milliseconds).
aTimer.Interval = 60000;
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program.");
Console.WriteLine(0 + ":" + 0);
Console.ReadLine();
}
// Specify what you want to happen when the Elapsed event is
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
j++;
if (j == 60)
{
Console.WriteLine("break");
j = 1;
i = i + 1;
}
if (i == 24)
{
i = 0;
}
if (j % 5 != 0 || (j == 0))
{
Console.WriteLine(i + ":" + j);
}
else if (j % 5 == 0)
{
Console.WriteLine("break");
}
}
}
I am not sure weather you want to use actual System time to start with or just the time since program execution started. Solution i am posting uses time since program started.
using System;
using System.Collections.Generic;
using System.Text;
using System.Timers;
namespace ConsoleApplication1
{
class Program
{
TimeSpan tt;
static void Main(string[] args)
{
Program p = new Program();
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(p.run));
t.Start();
while (true) ;
}
void run()
{
tt=new TimeSpan(0,1,0);
//Timer interval decides when even will be fired.
Timer t = new Timer(60000);
t.AutoReset = true;
t.Elapsed += new ElapsedEventHandler(t_Elapsed);
t.Start();
}
public void t_Elapsed(object sender, EventArgs e)
{
if (tt.Minutes % 5 == 0)
Console.WriteLine("Break");
Console.WriteLine(tt.Hours.ToString()+":"+tt.Minutes.ToString());
tt = tt.Add(new TimeSpan(0, 1, 0));
}
}
}