I am trying to benchmark something.
I have a loop like
for (int i = 1; i <= 1000; i++)
{
Thing thing = createThing(i);
DateTime startTime = DateTime.Now;
thing.ComputationallyExpensiveOp();
TimeSpan elapsed = DateTime.Now - startTime;
Console.WriteLine(String.Format("i = " + i + "\ttime = " + elapsed.TotalMilliseconds);
}
It looks like the first iteration, i = 1, takes a significant amount of time longer than it should (several orders of magnitude) based on how long the others take to complete.
The second iteration also seems too long often, although less obviously.
I feel like this is because the loop causes caching of a lot of values, which hadn't been set up in the first iteration.
Is there a way I can get the first iteration, i = 1, to be as "fast" (overhead-wise) as the rest, so that I really am timing only (as best as possible) thing.ComputationallyExpensiveOp().
At the moment it's obvious that the first iteration is not an accurate reflection of thing.ComputationallyExpensiveOp().
I tried already moving a "warm up" initialisation above the loop, but that didn't work.
Thing thing = createThing(1);
thing.ComputationallyExpensiveOp();
for (int i = 1; i <= 1000; i++)
{
thing = createThing(i);
DateTime startTime = DateTime.Now;
thing.ComputationallyExpensiveOp();
TimeSpan elapsed = DateTime.Now - startTime;
Console.WriteLine(String.Format("i = " + i + "\ttime = " + elapsed.TotalMilliseconds);
}
I have been using such for-loops for decades. And I never experienced, that such a for-loop was the cause of a delay during the first iteration.
I don't know anything about your Thing implementation, but I am quite sure the cause of your delay lies there. Not in the loop.
Copying the whole loop body outside "fixed" it for me
Thing thing = createThing(1);
DateTime startTime = DateTime.Now;
thing.ComputationallyExpensiveOp();
TimeSpan elapsed = DateTime.Now - startTime;
Console.WriteLine(String.Format("i = " + 1 + "\ttime = " + elapsed.TotalMilliseconds);
for (int i = 1; i <= 1000; i++)
{
thing = createThing(i);
startTime = DateTime.Now;
thing.ComputationallyExpensiveOp();
elapsed = DateTime.Now - startTime;
Console.WriteLine(String.Format("i = " + i + "\ttime = " + elapsed.TotalMilliseconds);
}
I'm not really sure of the cause, but now the first iteration has a runtime more like expected.
Related
I'm writing an app where a user specifies a length of time, length of an interval and a length of time in between intervals. I want to have a timer label showing the user the total time but then I also want to have a label showing the work status (recording if in the interval, break if between interval time and break end).
Heres an Example: Total time = 2 min, Interval = 20 seconds, Break = 10 seconds
In this example there will be 4 intervals. So from 0:00-0:19 I want to display "Recording" and then from 0:20-0:29 I want to display break and then from 0:30-0:49 I display "Recording" and 0:50-0:59 I display "Break" and so on. All while the timer counts the time.
So I thought this would be pretty straightforward but what seems to happen is the timer increments properly but after the 1st interval the label doesnt switch from break to recording until 0:31 or 0:32 so it looks a little delayed.
Here is the code I am using currently (Note obs is an object Im passing in that has data from user input).
int TotalInterval = obs.Interval + obs.Break;
int WorkingInterval = obs.Interval;
int NumberOfIntervals = (obs.Duration*60) / TotalInterval;
DateTime ObservationEnd = obs.DateCreated.AddMinutes(obs.Duration);
Timer.Text = "Starting Timer";
int minutes = 0;
int seconds = 0;
int InIntervalCounter = 0;
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
// called every 1 second
Timer.Text = "Started";
if (ObservationEnd < DateTime.UtcNow)
{
Timer.Text = "Time Over";
Results.IsVisible = true;
return false;
}
else
{
seconds++;
InIntervalCounter++;
if (InIntervalCounter > WorkingInterval)
IntervalOrBreak.Text = "Break";
if (InIntervalCounter > TotalInterval)
{
IntervalOrBreak.Text = "Recording";
InIntervalCounter = 0;
}
Timer.Text = "Time: " + minutes + ":" + seconds.ToString("D2");
return true;
}
});
I'm pretty new to app development/xamarin so any help is greatly appreciated.
Try using simple Threads with Thead.sleep() like this:
final long delay_millis = 100;
Thread thread_something;
thread_something = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
long start_time = SystemClock.elapsedRealtime();
// Do some task
long time_need_for_delay = (start_time + delay_millis) - SystemClock.elapsedRealtime();
if(time_need_for_delay > 0)
thread_something.sleep(time_need_for_delay);
} catch (Exception e) { }
}
}
});
thread_something.start();
after the 1st interval the label doesnt switch from break to recording
until 0:31 or 0:32 so it looks a little delayed.
If you want to display break from 0:20-0:29 and display "Recording" from 0:30-0:49, I think the if statement should change to InIntervalCounter >= WorkingInterval and InIntervalCounter >= TotalInterval, InIntervalCounter > WorkingInterval may cause the 1 second delay.
Scenario:
I have a iPad web app which connects to my Exchange server to display the visibility of meeting rooms in Outlook.
The clock must be very accurate (within 5 seconds of the Exchange Server time)
My problem is:
The iPad syncs its time with apples timeserver and there is no way of changing this without jailbreaking the iPad
The iPad clock is not in sync with our server
My current solution:
I have a Clock.aspx page which returns the current time and displays it in the correct div:
var getTime = function () {
$.get('Clock.aspx', function (data) {
$('#txt').html('<h1>' + data + '</h1>');
});
}
However:
This is very inefficient as the call to the server is every 10 seconds (this causes the iPad to crash once every 3/4 days)
What I would like to do:
Is pull the time from Clock.aspx once a hour and increment it using javascript for the rest of the time which will reduce the calls to the server significantly.
Please advise me on the best and most efficient way to do this.
If you have any other suggestions on ways to improve the efficiency I would also love to hear them.
Okay, this isn't perfect but meets my requirements for now - I'd once again appreciate it if more efficient and accurate solutions come up!
var hour = parseInt("<%=DateTime.Now.Hour %>", 10);
var minute = parseInt("<%=DateTime.Now.Minute %>", 10);
var second = parseInt("<%=DateTime.Now.Second %>", 10);
// var x = hour.tostring() +":"+ minute.tostring() +":"+ second.tostring();
// alert(x);
function showTime() {
second++;
if (second > 59) {
second = 0;
minute++;
}
if (minute > 59) {
minute = 0;
hour++;
}
minute = checkTime(minute);
second = checkTime(second);
var clock = hour.toString() + ":" + minute.toString() + ":" + second.toString();
document.getElementById("txt").innerHTML = "<h1>" + clock + "</h1>";
function checkTime(i) {
return (i < 10 ? '0' : '') + i;
}
}
setInterval('showTime()', 1000);
Having used my original answer for a few days I noticed that the sync was out, this script sync's with the server time every hour to re-sync the time accordingly, this means that the accuracy of the clock is very very close with the server. The previous script could lose upto 5 minutes per day. I hope this helps someone!
var serverDate;
function getServerDate() {
serverDate = new Date("<%=DateTime.Now %>");
}
function tick() {
serverDate.setSeconds(serverDate.getSeconds() + 1);
var min = serverDate.getMinutes();
var hour = serverDate.getHours();
var sec = serverDate.getSeconds();
if (min == 30) {
$.get('Clock.aspx?type=2', function (data) {
serverDate = new Date(data.split(">")[1].split("<")[0]);
min = serverDate.getMinutes();
hour = serverDate.getHours();
sec = serverDate.getSeconds();
});
}
if (hour < 10) hour = "0" + hour;
if (min < 10) min = "0" + min;
if (sec < 10) sec = "0" + sec;
document.getElementById("txt").innerHTML = "<h1>" + hour + ":" + min + ":" + sec; + "</h1>";
}
window.onload = function () {
getServerDate();
setInterval("tick()", 1000);
}
Edited to add that clock.aspx is a page which outputs DateTime.Now.ToString()
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));
}
}
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();
}
}
While profiling my application I found that DateTime.FromFileTime(long fileTime) is slow.
Does anyone know of a fast managed equivalent or the windows file time format?
[EDIT]
I was able to get some speed gains doing the following:
var timeStr = FastTimeStringFormat(new DateTime(fileTime + 0x701ce1722770000L, DateTimeKind.Utc).ToLocalTime()); // + 0x701ce1722770000L is the offset needed to convert to UTC DateTime
For more speed but less safety (no intra-day daylight savings time checks), you can cache the ToLocalTime offset (long) and spare the more expensive expensive ToLocalTime() call.
On App Start:
long fileTimeOffset = DateTime.Today.Subtract(DateTime.Today.ToUniversalTime()).Ticks + 0x701ce1722770000L;
Then in your critical path:
var timeStr = FastTimeStringFormat(new DateTime(fileTime + fileTimeOffset));
As it turned out ToString is very expensive and the following is faster.
public static unsafe string FastTimeStringFormat(DateTime time)
{
// modified version from the following post:
// http://geekswithblogs.net/akraus1/archive/2006/04/23/76146.aspx
// this one is also more accurate because of true divide by 10, beware of less accurate versions that do not use division
char* FixedCharArray = stackalloc char[13];
int hour = time.Hour; // Cache property values
int minute = time.Minute;
int second = time.Second;
int ms = time.Millisecond;
// hour
FixedCharArray[0] = (Char)('0' + hour / 10);
FixedCharArray[1] = (Char)('0' + hour % 10);
FixedCharArray[2] = ':';
// minute
FixedCharArray[3] = (Char)('0' + minute / 10);
FixedCharArray[4] = (Char)('0' + minute % 10);
FixedCharArray[5] = ':';
// seconds
FixedCharArray[6] = (Char)('0' + second / 10);
FixedCharArray[7] = (Char)('0' + second % 10);
FixedCharArray[8] = '.';
// miliseconds
FixedCharArray[9] = (Char)('0' + ms / 100);
FixedCharArray[10] = (Char)('0' + ms % 100 / 10);
FixedCharArray[11] = (Char)('0' + ms % 10);
return new String(FixedCharArray);
}
DateTime.FromFileTime() is implemented in managed code, there are no P/Invoke calls involved.
The performance hit you're experiencing might come from the conversion to local time that is performed internally. Try using DateTime.FromFileTimeUtc() instead, if at all possible.