How to implement clock() of c++ in c#? - c#

I want to implement clock method in c# and get difference time of two clock as describe in below code. I use timers ,stopwatch and DateTime in c# but i didn't get correct time as i get in c++.
C++ code is describe below :
clock_t start_time, diff_time;
start_time = clock();
int i = 0;
for(i=0;i<10;i++)
{
.....
}
diff_time = clock();
diff_time -= start_time;
C# code is :
var start_time = Stopwatch.StartNew();
for (int i = 0; i <= 10; i++)
i++;
var diff_time = Stopwatch.StartNew();
var diff_times = (start_time.ElapsedTicks - diff_time.ElapsedTicks);

I think StopWatch should be used to measure code performance and other similar comparisons. If is the case, ok.
Or else, maybe you should consider DateTime.Now
The C function clock() returns a clock_t value that is the number of clock ticks elapsed since the program started. The number of seconds used by the CPU is obtained dividing this result by CLOCKS_PER_SEC.
For DateTime, check:
https://learn.microsoft.com/pt-br/dotnet/api/system.datetime?view=netframework-4.8
-> Some parts below:
The DateTime value type represents dates and times measured in 100-nanosecond units called ticks. Example: in the gregorian calendar a ticks value of 31241376000000000L represents the date Friday, January 01, 0100 12:00:00 midnight.
...
If you are working with a ticks value that you want to convert to some other time interval, such as minutes or seconds, you should use the TimeSpan.TicksPerDay, TimeSpan.TicksPerHour, TimeSpan.TicksPerMinute, TimeSpan.TicksPerSecond, or TimeSpan.TicksPerMillisecond constant to perform the conversion. For example, to add the number of seconds represented by a specified number of ticks to the Second component of a DateTime value, you can use the expression
dateValue.Second + nTicks/Timespan.TicksPerSecond.
...

Here is a simple implementation of the Clock() function in C#
static void Main(string[] args)
{
long CLOCKS_PER_SEC = 10000000;
long lngElapsedTime_t = Clock();
long lngElapsedTime;
int i, j, k, m;
for (i = 0; i < 5000000; i++)
{
j = i / 50;
k = j * 50;
m = i - k;
if (m == 1) { Console.WriteLine(i); }
}
lngElapsedTime = (Clock() - lngElapsedTime_t) / CLOCKS_PER_SEC;
Console.WriteLine("<<{0}>> The time in Ticks", lngElapsedTime_t);
Console.WriteLine("<<{0}>> The elapsed time in seconds", lngElapsedTime);
Console.ReadKey();
}
public static long Clock()
{
long clock_t = (long)DateTime.Now.Ticks;
return clock_t;
}

Related

Time elapse computation in milliseconds C#

I need to time the execution of a code sequence written in C#. Using DateTime.Now I get incorrect values for the millisecond field.
For example:
int start_time, elapsed_time;
start_time = DateTime.Now.Millisecond;
for(int i = 0; i < N_ITER; i++) {
// cpu intensive sequence
}
elapsed_time = DateTime.Now.Millisecond - start_time;
elapsed_time gives negative values.
How may I replace DateTime in order to obtain the actual value of the elapsed time?
using System.Diagnostics;
//...
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < N_ITER; i++) {
// cpu intensive sequence
}
stopwatch.Stop();
elapsed_time = stopwatch.ElapsedMilliseconds;
Answer EDITED based on comments
This answer is only trying to count the total elapsed Milliseconds between two times, where the times are derived directly from DateTime.Now. As per the conversation, it's understood that DateTime.Now is vulnerable to outside influences. Hence the best solution would be to use the Stopwatch class. Here's a link that better explains (IMO) and discusses the performance between DateTimeNow, DateTime.Ticks, StopWatch.
Original Answer
The way you cast it into a int is the issue. You need better casting and extra elements :)
This may looks simple compared to an efficient timer. But it works:
DateTime startTime, endTime;
startTime = DateTime.Now;
//do your work
endTime = DateTime.Now;
Double elapsedMillisecs = ((TimeSpan)(endTime - startTime)).TotalMilliseconds;
There is a reference on the web, you may want to check out as well.
You're looking for the Stopwatch class. It is specifically designed to bring back high-accuracy time measurements.
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < N_ITER; i++)
{
// cpu intensive sequence
}
stopwatch.Stop();
var elapsed = stopwatch.ElapsedMilliseconds;
Stopwatch there are examples in the URL
https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=netframework-4.8
using System.Diagnostics;
//...
Stopwatch watch = new Stopwatch();
watch.Start();
// here the complex program.
//...
watch.Stop();
TimeSpan timeSpan = watch.Elapsed;
Console.WriteLine("Time: {0}h {1}m {2}s {3}ms", timeSpan.Hours, timeSpan.Minutes,
timeSpan.Seconds, timeSpan.Milliseconds);
DateTime.Millisecond just returns the millisecond fraction of the second, from 0-999. You would need to take the rest of the datetime into consideration when doing timings.
However, you should look at using the StopWatch class for these kinds of performance timings.
This works for me:
var lapsedTime = DateTime.Now.Subtract(beginTime).TotalMilliseconds;
Here is what I used to obtain the time for a simple computation:
class Program
{
static void Main(string[] args)
{
Decimal p = 0.00001m;
Decimal i = 0m;
DateTime start = new DateTime();
DateTime stop = new DateTime();
for (i = p; i <= 5; i = i + p)
{
Console.WriteLine("result is: " + i);
if (i==p) start = DateTime.Now;
if (i==5) stop = DateTime.Now;
}
Console.WriteLine("Time to compute: " + (stop-start));
}
}

Remaining time based on progress?

I would like to output the time remaining for a process on the following format:
d hh:mm:ss
When the process start, it sets a DateTime startTimevariable with the current time.
From there I have timer on my GUI that updates a label every second and here is what I have to calculated the remaining time:
TimeSpan timeRemaining = TimeSpan.FromTicks(DateTime.Now.Subtract(startTime).Ticks * (iProgress.Maximum - iProgress.Value) / iProgress.Value);
And using on the label as:
labelTimeRemaining.Text = timeRemaining.ToString(#"d\ hh\:mm\:ss");
However the time variation is displayed is going on very oddly jumping several minutes with getting into a steady mode.
I know it should jump on the begin but it should stabilize at some point right ?
I process about 1~3 records per second however the time remaining is jumping 10~20 minutes every update.
What am I doing wrong or how could I fix this issue ?
Let me know if u need more info or code.
UPDATE
Below is portion of the code I am using:
private Stopwatch _timer = new Stopwatch();
private int _total = 0;
private int _current = 0;
Start a thread or task with:
private void MyTask()
{
_timer.Reset();
_timer.Start();
for (int i = 0; i < _total; i++)
{
_current++;
Thread.Sleep(500);
}
_timer.Stop();
}
Create a winforms Timer with the below function to run every second:
if (_timer.IsRunning && _current > 0)
{
float elapsedMin = ((float)_timer.ElapsedMilliseconds / 1000) / 60;
float minLeft = (elapsedMin / _current) * (_total - _current);
TimeSpan eta = TimeSpan.FromMinutes(minLeft);
iStatus.Text = eta.ToString(#"d\ hh\:mm\:ss");
}
Based on the comments you provided, when you are working with 10K to 10M records, that a fluctuation is rather big as you could see. Here is the test example that will show you the fluctuation.
DateTime dt = DateTime.Now;
Thread.Sleep(3000);
TimeSpan ts = TimeSpan.FromTicks(DateTime.Now.Subtract(dt).Ticks * (100000 - 7) / 7);
Debug.WriteLine(ts.ToString());
Thread.Sleep(1000);
ts = TimeSpan.FromTicks(DateTime.Now.Subtract(dt).Ticks * (100000 - 9) / 9);
Debug.WriteLine(ts.ToString());
Also, even if you take care of integer division
DateTime dt = DateTime.Now;
Thread.Sleep(3000);
TimeSpan ts = TimeSpan.FromTicks((long)((double)DateTime.Now.Subtract(dt).Ticks * (100000.0 - 7.0) / 7.0));
Debug.WriteLine(ts.ToString());
Thread.Sleep(1000);
ts = TimeSpan.FromTicks((long)((double)DateTime.Now.Subtract(dt).Ticks * (100000.0 - 9.0) / 9.0));
Debug.WriteLine(ts.ToString());
But if you could normalize your records number to percents. Let's say you have 100K records, 1K is one percent and that is done in approximately 1000/2/60 around 8 minutes. After 32 minutes you will have 4% done. After another you will have 6% done and after another 24 minutes you will have around 9% done but lets say 10%. After more 30 minutes you should have 14% done. And now, if you update your textBox rarely the users will have the illusion that you really know how long it will take, and you will end up changing time for hour or two, but do it on every minute or on every percent changed (have you ever copied 30GB on Windows?)
DateTime dt1 = DateTime.Now;
DateTime dt2 = DateTime.Now;
dt2 = dt2.AddMinutes(32);
ts = TimeSpan.FromTicks(dt2.Subtract(dt1).Ticks * (100 - 4) / 4);
Debug.WriteLine(ts.ToString());
dt2 = dt2.AddMinutes(16);
ts = TimeSpan.FromTicks(dt2.Subtract(dt1).Ticks * (100 - 6) / 6);
Debug.WriteLine(ts.ToString());
dt2 = dt2.AddMinutes(24);
ts = TimeSpan.FromTicks(dt2.Subtract(dt1).Ticks * (100 - 10) / 10);
Debug.WriteLine(ts.ToString());
dt2 = dt2.AddMinutes(30);
ts = TimeSpan.FromTicks(dt2.Subtract(dt1).Ticks * (100 - 14) / 14);
Debug.WriteLine(ts.ToString());

C# Timer counter in xx.xx.xx format

I have a counter that counts up every 1 second and add 1 to an int.
Question
How can I format my string so the counter would look like this:
00:01:23
Instead of:
123
Things I've tried
Things I've tried so far:
for (int i = 0; i < 1; i++)
{
_Counter += 1;
labelUpTime.Text = _Counter.ToString();
}
My timer's interval is set to: 1000 (so it adds 1 every second).
I did read something about string.Format(""), but I don't know if it is applicable.
Thanks if you can guide me through this :D!
Use a TimeSpan:
_Counter += 1;
labelUpTime.Text = TimeSpan.FromSeconds(_Counter).ToString();
You could make it a TimeSpan (for that's what it is, a span of time), then format that:
labelUpTime.Text = TimeSpan.FromSeconds(_Counter).ToString();
Don't use a counter, and don't rely on the timer firing exactly every second. It won't. Do something like this.
class TimerTest
{
private DateTime _start = DateTime.Now;
private Timer _timer = new Timer(1000);
public TimerTest()
{
// (DateTime.Now - _start) returns a TimeSpan object
// Default TimeSpan.ToString() returns 00:00:00
_timer.Elapsed = (o, e) => labelUpTime.Text = (DateTime.Now - _start).ToString();
}
}
You can adjust the formatting with the TimeSpan.ToString method.
TimeSpan timer = new TimeSpan(0);
and on your interval:
timer += TimeSpan.FromSeconds(1);
Use timespan. To add a second use
mytimespan.Add(new TimespanFromSeconds(1));
Console.WriteLine(mytimespan); //Output in the form of xx:xx:xx
http://www.dotnetperls.com/timespan
it worked well for me
public TimeSpan ElapsedTimeFormatted
{
get
{
if (FinishedOn != null &&
StartedAt != null)
{
TimeSpan durationCount = new TimeSpan();
int hours = 0;
int minutes = 0;
int seconds = 0;
var times = Segments.Select(c => c.ElapsedTimeFormatted).ToList();
foreach (var time in times)
{
TimeSpan timeParse = TimeSpan.Parse(time);
hours = hours + (int)timeParse.Hours;
minutes = minutes + (int)timeParse.Minutes;
seconds = seconds + (int)timeParse.Seconds;
durationCount = new TimeSpan(hours, minutes, seconds);
}
return durationCount;
}
return new TimeSpan();
}
}

Calculate the average TimeSpan between a collection of DateTimes

Let's say we're tracking the times when a user is performing a certain action, and we want to know the average time between said actions.
For example, if the user performed this action at these times:
today, 1 PM
today, 3 PM
today, 6 PM
The result would be 2.5 hours.
I actually have solved this already, but I felt my solution was more complicated than necessary. I'll post it as an answer.
It seems that you are basically looking for Max - Min divided by Count.
public TimeSpan? Average
{
get
{
var diff = _dateTimes.Max().Subtract(_dateTimes.Min());
var avgTs = TimeSpan.FromMilliseconds(diff.TotalMilliseconds / (_dateTimes.Count() - 1));
return avgTs;
}
}
Make sure you check that there is more than one DateTime.
Update: Even more accurate if you use Ticks.
TimeSpan.FromTicks(diff.Ticks / (_dateTimes.Count() - 1));
I recently had a similar task in where I had a long running operation iterating over thousands of rows with 20-30 iterations within each.
void LongRunningOperation()
{
int r = 5000;
int sR = 20;
List<TimeSpan> timeSpanList = new List<TimeSpan>();
for (int i = 0; i < r; i++)
{
DateTime n = DateTime.Now; // Gets start time of this iteration.
for (int x = 0; x < sR; x++)
{
// DOING WORK HERE
}
timeSpanList.Add(DateTime.Now - n); // Gets the length of time of iteration and adds it to list.
double avg = timeSpanList.Select(x => x.TotalSeconds).Average(); // Use LINQ to get an average of the TimeSpan durations.
TimeSpan timeRemaining = DateTime.Now.AddSeconds((r - i) * avg) - DateTime.Now;
// Calculate time remaining by taking the total number of rows minus the number of rows done multiplied by the average duration.
UpdateStatusLabel(timeRemaining);
}
}
This is how I solved it, but I don't like it much:
public class HistoryItem
{
private IEnumerable<DateTime> _dateTimes;
public TimeSpan? Average
{
get {
TimeSpan total = default(TimeSpan);
DateTime? previous = null;
int quotient = 0;
var sortedDates = _dateTimes.OrderBy(x => x);
foreach (var dateTime in sortedDates)
{
if (previous != null)
{
total += dateTime - previous.Value;
}
++quotient;
previous = dateTime;
}
return quotient > 0 ? (TimeSpan.FromMilliseconds(total.TotalMilliseconds/quotient)) as TimeSpan? : null;
}
}
}

DateTime.AddDays or new DateTime

I'm creating a list of a month's worth of dates. I'm wondering what will be more efficient
List<DateTime> GetDates(DateTime StartDay) {
List<DateTime> dates = new List<DateTime>();
int TotalDays=StartDay.AddMonths(1).AddDays(-1).Day;
for (int i=1; i<TotalDays; i++) {
dates.Add(new DateTime(StartDay.Year, StartDay.Month, i));
}
return dates;
}
or
List<DateTime> GetDates(DateTime StartDay) {
List<DateTime> dates = new List<DateTime>();
DateTime NextMonth = StartDay.AddMonths(1);
for (DateTime curr=StartDay; !curr.Equals(NextMonth); curr=curr.AddDays(1)) {
dates.Add(curr);
}
return dates;
}
basically, is new DateTime() or DateTime.addDays more efficient.
UPDATE:
static void Main(string[] args) {
System.Diagnostics.Stopwatch sw=new System.Diagnostics.Stopwatch();
long t1, t2, total;
List<DateTime> l;
DateTime begin = DateTime.Now;
total = 0L;
for (int i=0; i<10; i++) {
sw.Start();
l = GetDates(begin);
sw.Stop();
sw.Stop();
t1 = sw.ElapsedTicks;
sw.Reset();
sw.Start();
l = GetDates2(begin);
sw.Stop();
t2=sw.ElapsedTicks;
total += t1- t2;
Console.WriteLine("Test {0} : {1} {2} : {3}", i,t1,t2, t1- t2);
}
Console.WriteLine("Total: {0}", total);
Console.WriteLine("\n\nDone");
Console.ReadLine();
}
static List<DateTime> GetDates(DateTime StartDay) {
List<DateTime> dates = new List<DateTime>();
int TotalDays=StartDay.AddMonths(10000).AddDays(-1).Day;
for (int i=1; i<TotalDays; i++) {
dates.Add(new DateTime(StartDay.Year, StartDay.Month, i));
}
return dates;
}
static List<DateTime> GetDates2(DateTime StartDay) {
List<DateTime> dates = new List<DateTime>();
DateTime NextMonth = StartDay.AddMonths(10000);
for (DateTime curr=StartDay; !curr.Equals(NextMonth); curr=curr.AddDays(1)) {
dates.Add(curr);
}
return dates;
}
Test 0 : 2203229 63086205 : -60882976
Test 1 : 63126483 102969090 : -39842607
Test 2 : 102991588 93487982 : 9503606
Test 3 : 93510942 69439034 : 24071908
Test 4 : 69465137 70660555 : -1195418
Test 5 : 70695702 68224849 : 2470853
Test 6 : 68248593 63555492 : 4693101
Test 7 : 63578536 65086357 : -1507821
Test 8 : 65108190 64035573 : 1072617
Test 9 : 64066128 64933449 : -867321
Total: -62484058
Done
results are consistently negative... way negative, so, looks like the constructor and integer test is the more efficient method.
Measure it - write a test program and see which one takes less time.
I believe datetime operations return new datetime structures so you will be creating new instances either way.
http://msdn.microsoft.com/en-us/library/system.datetime.aspx
Unless you are doing some financial processing then I would worry more about readability than performance here. Only start worrying about performance somewhere like here if it's a proven bottleneck.
Since they both do the same thing in the end, there isn't much of a difference.
If you're looking for efficiency, just use ticks. All (that I've seen) calls in DateTime are eventually converted into ticks before any math gets done.
It's really hard to imagine a case in which this would make a significant difference, but Reflector shows that the AddDays technique should be more efficient.
Compare the core logic of AddDays (from Add(Double, Int32))
long num = (long) ((value * scale) + ((value >= 0.0) ? 0.5 : -0.5));
if ((num <= -315537897600000L) || (num >= 0x11efae44cb400L)) {
// Throw omitted
}
return this.AddTicks(num * 0x2710L);
To the core logic of the DateTime(int, int, int) constructor (from DateToTicks):
if (((year >= 1) && (year <= 0x270f)) && ((month >= 1) && (month <= 12)))
{
int[] numArray = IsLeapYear(year) ? DaysToMonth366 : DaysToMonth365;
if ((day >= 1) && (day <= (numArray[month] - numArray[month - 1])))
{
int num = year - 1;
int num2 = ((((((num * 0x16d) + (num / 4)) - (num / 100)) + (num / 400)) + numArray[month - 1]) + day) - 1;
return (num2 * 0xc92a69c000L);
}
}
// Throw omitted
AddDays just converts the specified number of days to the equivalent number of ticks (a long) and adds it to the existing ticks.
Creating a new DateTime using the year/month/day constructor requires many more calculations. That constructor has to check whether the specified year is a leap year, allocate an array of days in each month, perform a bunch of extra operations, just to finally get the number of ticks those three numbers represent.
Edit: DateTime.AddDays(int) is faster than new DateTime(int, int, int), but your first algorithm is faster than the second algorithm. This is probably because the iteration costs are much higher in the second algorithm. As you observed in your edit, this might well be because DateTime.Equals is more expensive than comparing integers.
Here is a working test program, with the algorithms implemented so that they can actually be compared (they still need work, though):
class Program
{
static void Main(string[] args)
{
IList<DateTime> l1, l2;
DateTime begin = new DateTime(2000, 1, 1);
Stopwatch timer1 = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
l1 = GetDates(begin);
timer1.Stop();
Stopwatch timer2 = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
l2 = GetDates2(begin);
timer2.Stop();
Console.WriteLine("new DateTime: {0}\n.AddDays: {1}",
timer1.ElapsedTicks, timer2.ElapsedTicks);
Console.ReadLine();
}
static IList<DateTime> GetDates(DateTime StartDay)
{
IList<DateTime> dates = new List<DateTime>();
int TotalDays = DateTime.DaysInMonth(StartDay.Year, StartDay.Month);
for (int i = 0; i < TotalDays; i++)
dates.Add(new DateTime(StartDay.Year, StartDay.Month, i + 1));
return dates;
}
static IList<DateTime> GetDates2(DateTime StartDay)
{
IList<DateTime> dates = new List<DateTime>();
DateTime NextMonth = StartDay.AddMonths(1);
for (DateTime curr = StartDay; !curr.Equals(NextMonth); curr = curr.AddDays(1))
dates.Add(curr);
return dates;
}
} // class
Output (I added the commas):
new DateTime: 545,307,375
.AddDays: 180,071,512
These results seem pretty clear to me, though honestly I thought they'd be a lot closer.
I agree with Mark. Test both methods yourself and see which one is faster. Use the Stopwatch class to get accurate timings of how long each method takes to run. My first guess is that since both end up creating new structures anyway, that any speed difference will be negligible. Also, with only generating a month's worth of dates (31 days maximum), I don't think either method will be that much slower than the other. Perhaps is you you were generating thousands or millions of dates, it would make a difference, but for 31 dates, it's probably premature optimization.

Categories

Resources