TimeSpan into Microseconds?
Asked Answered
S

4

7

hello again my question if it is possible to print microsencods using TimesSpan in C#.

i have the next example:

DateTime startTime = DateTime.Now;
..../some code
DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);
Label3.Text=(totalTimeTaken.Milliseconds).ToString();

this code allows me to display in milliseconds but i need to display Microseconds is there a way to change it to Microseconds or do I have to use something else?

have to edit my question: my goal is to measure the time that is spent between the 2 DateTime, since it is very few lines of code the milliseconds just wont cut it, thats the reason i need the microseconds.

Sugden answered 18/7, 2012 at 18:12 Comment(4)
TimeSpan does not support that granularity.Manned
@PeterRitchie TimeSpan by itself does support this granularity - it's a simple little structure with ticks granular to one tenth of a microsecond. The problem lies with the DateTime: its granularity is much worse.Famulus
If your TimeSpan is, say, 00:00:02.3456789, the Milliseconds property will only give you the part 345, as an Int32 (int). What you want is TotalMilliseconds. That's a Double and will include all the digits. See my answer.Jammiejammin
@dasblinkenlight, good point, however TimeSpan has a bug as well: github.com/dotnet/corefx/issues/32430Riggall
K
11

The highest resolution you will find will be via the Stopwatch class. If your CPU supports a high resolution timer, the Stopwatch class will use it. You can check this via the IsHighResolution and/or Frequency properties.

This is the class you should be using for performance measurements, not DateTime.

EDIT: I just learned something new about DateTime. From the docs...

Time values are measured in 100-nanosecond units called ticks, and a particular date is the number of ticks since 12:00 midnight, January 1, 0001 A.D. (C.E.) in the GregorianCalendar calendar (excluding ticks that would be added by leap seconds). For example, a ticks value of 31241376000000000L represents the date, Friday, January 01, 0100 12:00:00 midnight. A DateTime value is always expressed in the context of an explicit or default calendar.

However, the resolution of DateTime.Now is still about 15ms, so it won't work (which makes the documentation misleading at best...) Use the Stopwatch.

Kaylor answered 18/7, 2012 at 18:17 Comment(4)
Anyone care to shed some light on the downvotes? What is incorrect here exactly?Kaylor
Um it appears that I hit down instead of up on accident earlier. Sorry ><Commencement
after reading your anwsers and trying all examples it looks like i have to use stopwatch now going to investigate how it works thanks to allSugden
@JUAN: It's really simple. Just replace your first call to DateTime.Now with var sw = StopWatch.StartNew(); and the last call with sw.Stop(). Then you can read the interval with as high a resolution as your CPU supports.Kaylor
C
1

Use System.Diagnostics.Stopwatch if you need a high level precision.

From the code sample if looks like you are trying to time something. DateTime is a poor structure for that. Please see Eric Lippert's article "Precision and Accuracy of DateTime" for more information.

Now, the question “how much time has elapsed from start to finish?” is a completely different question than “what time is it right now?” If the question you want to ask is about how long some operation took, and you want a high-precision, high-accuracy answer, then use the StopWatch class. It really does have nanosecond precision and accuracy that is close to its precision.

Commencement answered 18/7, 2012 at 18:14 Comment(10)
@PeterRitchie That's interesting. What are those circumstances?Commencement
@PeterRitchie: The documentation says that it will use the CPU's high performance counter if available. It it isn't available (rare these days) then you have no options anyway.Kaylor
@Commencement I'm not sure of all circumstances; but as Ed S. points out, one is whether or not the computer has hi-res performance counter; permissions come in to play too.Manned
@PeterRitchie: I didn't realize permissions came into play. Would you mind expanding on that for me?Kaylor
@EdS. The extent to which a user does or does not have access to performance timers doesn't seem to be documented. But, logins need to be added to the Performance Log User group (through secpol--this doesn't show up in Users/Groups) if the user is in a group that doesn't already have access. I believe Power and Admins have access, and Users don't; but, I can't confirm. I think being in a VM, difference desktop sessions, remote access, all effect performance counter permissions...Manned
@PeterRitchie: Interesting, I'm going to have to try that out. I work on a fairly locked down system, but it still runs Windows, and most of our customers have IT policies which prevent them from running as admins (thank God...). I have some performance measuring code (C++) which uses the high performance timer API. I'd hate to think that these measurements could be incorrect at times, or that more serious problems may occur if used. I'll run some tests. Thanks again.Kaylor
@PeterRitchie Thank you very much for the information. I had no idea.Commencement
@EdS. You can test if you have access to hi-res timers by checking Stopwatch.IsHighResolution. If it's false, the computer either doesn't have hi-res timers, or there was a permission issue.Manned
@PeterRitchie: Yeah, I noted that in my response earlier, but my specific scenario is C++, so not Stopwatch.Kaylor
@EdS. QueryPerformanceFrequency will return failure or a frequency of 0 in those cases. I assume GetLastError will tell you if there is a permission issue.Manned
C
1

You can use the DateTime class. DateTime has a property called Ticks.

DateTime.Ticks

From the link:

"A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond.

The value of this property represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001, which represents DateTime.MinValue. It does not include the number of ticks that are attributable to leap seconds."

DateTime dt1 = DateTime.Now;
// do stuff here...
DateTime dt2 = DateTime.Now;

long nanoseconds = (dt2.Ticks - dt1.Ticks) * 100;
Craze answered 18/7, 2012 at 18:18 Comment(2)
This won't work; DateTime.Now does not use the high performance timer (if available), so the resolution is still low.Kaylor
It's understandable; the documentation is misleading.Kaylor
J
1

Others have written nice thing on the precision you can expect when you subtract two DateTime.Now. But there's another important point: Use totalTimeTaken.TotalMilliseconds, not totalTimeTaken.Milliseconds. In general the number will have 4 decimals.

To get microseconds, simply use 1000.0 * totalTimeTaken.TotalMilliseconds. There will in general be one decimal after the decimal point. But to repeat: Not all those digits will be reliable with typical hardware and implementation.

Jammiejammin answered 18/7, 2012 at 19:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.