Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

now.ticks does not work

40 views
Skip to first unread message

Willie jan

unread,
Aug 17, 2005, 9:41:31 AM8/17/05
to
place this behind a button that fills a listbox.
as you will see the time is now and then 0 or filled in????????????
by hitting the button.

is there a way to determine the real elapsed time?

thanks, Willie

Dim T As Double

T = Now.Ticks

System.Threading.Thread.Sleep(3)

T = Now.Ticks - T

ListBox1.Items.Insert(0, T.ToString("0000000000000000"))


Armin Zingler

unread,
Aug 17, 2005, 9:48:54 AM8/17/05
to
"Willie jan" <unk...@unkown.com> schrieb

> place this behind a button that fills a listbox.
> as you will see the time is now and then 0 or filled in????????????
> by hitting the button.
>
> is there a way to determine the real elapsed time?
>
> thanks, Willie
>
> Dim T As Double

Dim t as long

Ticks is long, not double.

> T = Now.Ticks
>
> System.Threading.Thread.Sleep(3)
>
> T = Now.Ticks - T
>
> ListBox1.Items.Insert(0, T.ToString("0000000000000000"))


The *unit* of Now.Ticks is 100 nano seconds.
The *resolution* is AFAIR 0.01 seconds.

Sleep longer than 0.01 seconds and you'll see a difference.

Higher resolution: Environment.Tickcount.
Even higher resolution: High performance counter. (see
QueryPerformanceCounter and QueryPerformanceFrequency API functions)


Armin

Ross Presser

unread,
Aug 17, 2005, 10:20:00 AM8/17/05
to

Not sure what's wrong with your code, but here's what I would have done:

Dim T as DateTime

T = Now

System.Threading.Thread.Sleep(3)

Dim D as TimeSpan

D = Now.Subtract(T)

ListBox1.Items.Insert(0, D.ToString())

Jay B. Harlow [MVP - Outlook]

unread,
Aug 17, 2005, 10:53:32 AM8/17/05
to
Willie,
As the others suggest, you should use Long or DateTime to store T.

DateTime has a "resolution" of 100-nanoseconds, its precession can vary, in
that although it is based on units of 100-nanosecond its resolution or
precision is based on the system timer (which may be as course as .01
seconds)

QueryPerformanceCounter has a resolution of nanoseconds or smaller (its
precession is the QueryPerformanceFrequency value). Its based on a
"high-resolution performance counter", which I understand is a special hard
ware counter on some CPUs...

Tickcount has a resolution of microseconds.

There is an MSDN Magazine article that discusses timing blocks of code,
however I am having trouble finding it right now, it may be the third link
below, however it doesn't feel right...

Use QueryPerformanceCounter to Time code in VB.NET:
http://support.microsoft.com/default.aspx?scid=kb;en-us;306978

Not sure if the following will help or not:

Comparing the Timer Classes in the .NET Framework Class Library
http://msdn.microsoft.com/msdnmag/issues/04/02/TimersinNET/default.aspx

Implement a Continuously Updating, High_Resolution Time Provider for Windows
http://msdn.microsoft.com/msdnmag/issues/04/03/HighResolutionTimer/default.aspx


I normally use QueryPerformanceCounter as its in the units used by
Performance Counters:

Something like:

Declare Function QueryPerformanceCounter Lib "Kernel32" (ByRef counter
As Long) As Boolean
Declare Function QueryPerformanceFrequency Lib "Kernel32" (ByRef
frequency As Long) As Boolean


' set some time var
Dim start, finish, frequency As Long
QueryPerformanceFrequency(frequency)
QueryPerformanceCounter(start)

' work

QueryPerformanceCounter(finish)
Dim time As TimeSpan = TimeSpan.FromSeconds((finish - start) /
frequency)

Alternatively you can use DateTime:

' set some time var
Dim start, finish As DateTime
start = DateTime.Now

' work

finish = DateTime.Now
Dim time As TimeSpan = finish.Subtract(start)

A third alternative would be to use "Ticks"

' set some time var
Dim start, finish As Integer
start = Environment.TickCount

' work

' set second time var and comapre to get result
finish = Environment.TickCount
Dim time As TimeSpan = TimeSpan.FromMilliseconds(finish - start)

My understanding is that QueryPerformanceCounter will normally be a higher
resolution then Environment.TickCount, however QueryPerformanceCounter may
not be available.

VB.NET 2005 (aka Whidbey, due out later in 2005) simplifies the choice by
providing a System.Diagnostics.Stopwatch class that will automatically
choose between QueryPerformanceCounter & Environment.TickCount...

http://lab.msdn.microsoft.com/vs2005/

http://msdn2.microsoft.com/library/ebf7z0sw.aspx

Hope this helps
Jay


"Willie jan" <unk...@unkown.com> wrote in message
news:43033dea$0$31942$dbd4...@news.euronet.nl...

Willie jan

unread,
Aug 18, 2005, 4:38:21 AM8/18/05
to
the problem i have is that the now.ticks is not relayable.
the first click returns 0, the second returns 2.6ms
i will check out your QueryPerformanceCounter

thanks.

"Jay B. Harlow [MVP - Outlook]" <Jay_Har...@msn.com> schreef in bericht
news:O62w1tzo...@TK2MSFTNGP09.phx.gbl...

Willie jan

unread,
Aug 18, 2005, 4:39:59 AM8/18/05
to
my sleep was 3 ms, so it should show it.
the strange thing is, sometimes you get a value >0, but not always.

I use this to determine the database call time used.

"Armin Zingler" <az.n...@freenet.de> schreef in bericht
news:u39p$JzoFH...@TK2MSFTNGP12.phx.gbl...

Willie jan

unread,
Aug 18, 2005, 4:41:42 AM8/18/05
to
when i run your coude i get this when hitting the button sereval times:

00:00:00
00:00:00
00:00:00
00:00:00
00:00:00
00:00:00

"Ross Presser" <rpre...@NOSPAMgmail.com.invalid> schreef in bericht
news:1o8zddzt...@rosspresser.dyndns.org...

Willie jan

unread,
Aug 18, 2005, 4:43:40 AM8/18/05
to
when i use your code it get:

00:00:00
00:00:00.0156250


00:00:00
00:00:00
00:00:00

00:00:00.0156250
00:00:00.0156250


00:00:00
00:00:00

So it's basically the same problem. Now and then the result is >0, but often
it returns 0 ?????


"Ross Presser" <rpre...@NOSPAMgmail.com.invalid> schreef in bericht
news:1o8zddzt...@rosspresser.dyndns.org...

Cor Ligthert [MVP]

unread,
Aug 18, 2005, 4:54:37 AM8/18/05
to
Willie,

This method or any timing method on a moderen multi processing environment
will never be reliable just because you don't know what process is started
or done while your application is sleeping and takes the resources.

I hope this helps,

Cor


Armin Zingler

unread,
Aug 18, 2005, 5:26:51 AM8/18/05
to
"Willie jan" <unk...@unkown.com> schrieb

> my sleep was 3 ms, so it should show it.

As I wrote, the resolution is 0.01s, and 3 ms < 0.01s

> the strange thing is, sometimes you get a value >0, but not always.

If the timer happend to tick just between the first and 2nd call to 'Now',
you get a difference.

Have a look @ a time scale: (Use a fixed font for viewing!)

0.03 seconds:

[---------|---------|---------]
^ ^

The "|" represent the ticks. They indicate at which point 'Now' returns a
new value. As the resolution is 0.01 seconds, this happens every 0.01
seconds. 'Now' returns 0.00 til the first tick. 'Now' returns 0.01 between
the first and 2nd tick. It returns 0.02 after the 2nd tick.

The "^" indicate the points where the measurements take place. If something
takes 3ms, you get 0.00 and 0.00 twice because there was no tick inbetween.
Difference = 0.

[---------|---------|---------]
^ ^

If one measurement takes place before, the other one after the tick, the
action took still 0.003 seconds, but you get a difference of 0.01 s, as you
see.

That's why you can get different results. As I've suggested already, use a
timer with a higher resolution.

Even if an action took 0.9999 seconds, you might get 0 as the difference as
shown here:

[---------|---------|---------]
^ ^

You see?


Armin

Jay B. Harlow [MVP - Outlook]

unread,
Aug 18, 2005, 9:58:04 AM8/18/05
to
Willie,

| the problem i have is that the now.ticks is not relayable.
I agree: Using it to time code that is faster then the quantum that is used
to update it is not very "reliable". However! I consider Now.Ticks to be a
very reliable number!

Read my & Armin's message again, it (Now.Ticks) is very reliable as it will
be updated every quantum based on the OS, where quantum is OS based (see
first link below). However it is not very precise, because the quantum used
to update it is relatively course.

In other works Now.Ticks is reliably updated approximately every .01 seconds
as Armin suggests (as its based on the OS "clock"), however you are trying
to time something that only lasts .003 seconds. Simple math suggests that
.003 goes into .01 3 & 1/3 times. If you were timing something that took
seconds or minutes, then Now.Ticks would be very reliable!

For more details on the Precision & Resolution of Now.Ticks, see:

"Precision" of DateTime (100-nanoseconds):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdatetimeclasstopic.asp

"Resolution" of DateTime.Now (.01 seconds):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDateTimeClassNowTopic.asp

Where "Precision" is how many digits of "time" a DateTime contains, while
"Resolution" is how accurate those digits are when using DateTime.Now.

Hope this helps
Jay

"Willie jan" <unk...@unkown.com> wrote in message

news:4304485d$0$20022$dbd4...@news.euronet.nl...

Ross Presser

unread,
Aug 18, 2005, 9:38:10 AM8/18/05
to
On Thu, 18 Aug 2005 11:26:51 +0200, Armin Zingler wrote:

> Even if an action took 0.9999 seconds, you might get 0 as the difference as
> shown here:
>
> [---------|---------|---------]

Typo; I think you meant 0.09999 seconds.

Jay B. Harlow [MVP - Outlook]

unread,
Aug 18, 2005, 10:00:51 AM8/18/05
to
Willie,
I should add: as Cor mentions.

Using Now.Ticks or QueryPerformanceCounter or any other timing method in
Windows is not going to be reliable, as there are other processes that are
running, that can change the outcome of the timing. I believe one or more of
the articles I gave discuss this "interference" of other processes.


Normally I run my test 5 or more times & average the results.

Hope this helps
Jay

"Willie jan" <unk...@unkown.com> wrote in message

news:4304485d$0$20022$dbd4...@news.euronet.nl...

Armin Zingler

unread,
Aug 18, 2005, 10:17:38 AM8/18/05
to
"Ross Presser" <rpre...@NOSPAMgmail.com.invalid> schrieb


Yes! You're right. Thanks for correction.


Armin

Willie jan

unread,
Aug 19, 2005, 3:45:02 AM8/19/05
to
aaahhhh now i see the light!

thanks for your clear answer.

Willie.

"Armin Zingler" <az.n...@freenet.de> schreef in bericht

news:e1IIWd9o...@tk2msftngp13.phx.gbl...

Willie jan

unread,
Aug 19, 2005, 3:53:54 AM8/19/05
to
the point is that my application logs the time used to run a certain
database call, and no average can me calculated. Now something they get a
value, and sometimes a 0. That's my problem right now.
When the call is for instance 30-60 ms, it's no problem with the ticks not
showing the right amount because the longer the calls takes, the less offset
in % is there.
But when a call that is made is 5ms than 1 less or more is 20%...

Willie.


"Jay B. Harlow [MVP - Outlook]" <Jay_Har...@msn.com> schreef in bericht

news:OpX9B1$oFHA...@TK2MSFTNGP14.phx.gbl...

Jay B. Harlow [MVP - Outlook]

unread,
Aug 19, 2005, 10:11:52 AM8/19/05
to
Willie,

| the point is that my application logs the time used to run a certain
| database call, and no average can me calculated.
OK. I believe my comment still stands.

My first point is you need to use QueryPerformanceCounter or another higher
resolution timer (the multiple media timer for example) to time the database
call. I believe one or more of the articles I gave discuss the various high
resolution timers available.

My second point is that an individual database call may be "off" (because of
other processes running & possibly the network itself), but when you average
the times of 100 or 1000 or more database calls, it will be increasingly
more "reliable"...

I would recommend QueryPerformanceCounter as it has the same resolution as
System.Diagnostics.PerformanceCounter. In addition to (instead of?) logging
the time of a certain database call, I would define a number of
PerformanceCounters (aka Instrumentation) that tracked items such as:
- database calls per second
- seconds per database call
- number of database calls
- total seconds of all database calls

- number of "transactions" (unit of work)
- number of database calls per "transaction"
- seconds per "transaction"
- "transactions" per second
- total seconds of all "transactions"

Where an individual "transaction" makes one or more database calls. For
example saving a shopping cart is the transaction. The act of saving the
shopping cart will call the database for the shopping cart shipping/billing
info (the header), plus call the database once for each item in the shopping
cart (the detail).

Generally you only need one of "calls per second" & "seconds per call",
depending on the what the average length of the item being measured is.
Sometimes I include both as its not obvious which one will be more useful.

By defining PerformanceCounters you are able to use tools such as PerfMon
(Start - Control Panel - Administrative Tools - Performance') to see how
your app is performing overall. Having the log may help identify specific
problems once PerfMon has identified a problem...

Post if you would like links on Performance Counters & Instrumentation in
.NET.

Hope this helps
Jay

"Willie jan" <unk...@unkown.com> wrote in message

news:43058f72$0$66366$dbd4...@news.euronet.nl...

Armin Zingler

unread,
Aug 19, 2005, 10:54:27 AM8/19/05
to
"Jay B. Harlow [MVP - Outlook]" <Jay_Har...@msn.com> schrieb

> My second point is that an individual database call may be "off"
> (because of other processes running & possibly the network itself),


Unless you set the priority *very* high. ;-) But the user probably won't
like this. (and it's not good design to do it just for more accurate
measuring (apart from testing purposes)).


Armin

Stephany Young

unread,
Aug 19, 2005, 11:18:50 PM8/19/05
to
There are 2 more options that may help you out.

1. System.Environment.TickCount give milliseconds

Dim _t As Integer = Environment.TickCount

...

Console.Writeline(Environment.TickCount - _t1)

You will still get 0 if the start aend end occur in the same millisecond.

2. TimeSpan.TotalMilliseconds

Dim _t As DateTime = DateTime.Now

...

Console.Writeline("DateTime.Now.Subtract(_t).TotalMilliseconds)

This will give milliseconds including fractions of milliseconds.


"Willie jan" <unk...@unkown.com> wrote in message

news:43058f72$0$66366$dbd4...@news.euronet.nl...

Jay B. Harlow [MVP - Outlook]

unread,
Aug 21, 2005, 2:41:52 PM8/21/05
to
Stephany,
| 1. System.Environment.TickCount give milliseconds

| You will still get 0 if the start aend end occur in the same millisecond.
Agreed as I believe Armin & I have both stated that.

| 2. TimeSpan.TotalMilliseconds
| Dim _t As DateTime = DateTime.Now

| This will give milliseconds including fractions of milliseconds.

No, it will not give "fractions of milliseconds" it will be "rounded up" to
every 10 or 55 milliseconds based on the OS.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDateTimeClassNowTopic.asp

Although DateTime.Now includes fractions of a millisecond, it is based on
the system timer, which is every 10 or 55 milliseconds.

Hope this helps
Jay


"Stephany Young" <noone@localhost> wrote in message
news:%23Y$zpXTpF...@TK2MSFTNGP12.phx.gbl...

Jay B. Harlow [MVP - Outlook]

unread,
Aug 21, 2005, 2:52:38 PM8/21/05
to
Armin,
My understanding is even when a thread or process's priority is *very* high,
the OS may use "priority boosting" to raise the lesser threads up to give
them a slight chance of having some time.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/priority_boosts.asp

Jay

"Armin Zingler" <az.n...@freenet.de> wrote in message
news:%2384LJ4M...@tk2msftngp13.phx.gbl...

Armin Zingler

unread,
Aug 22, 2005, 8:09:31 AM8/22/05
to
"Jay B. Harlow [MVP - Outlook]" <Jay_Har...@msn.com> schrieb
> Armin,
> My understanding is even when a thread or process's priority is
> *very* high, the OS may use "priority boosting" to raise the lesser
> threads up to give them a slight chance of having some time.
>
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/priority_boosts.asp

Yes, but the higher the priority the better the results when measuring the
time because the probability of being interrupted will be lower. If the
base priorty is 31, it wouldn't help other threads anyway (Willie, "don't
try this at home" - unless you know what you're doing). I didn't want to go
into details as it was not meant really seriously.

(BTW, the system's crystal is running @ 14,318,181 MHz. The value returned
by QueryPerformanceFrequency is 3,579,545. This is the first value divided
by 4. Means, every 4th base tick, the HP counter is increased.
Another divider is 12. Result=1193182 (14318181/12). (Actually 1193180 has
been used but nobody really knows why). On former systems (or still?), every
65536 (0x10000) tick, the timer interrupt has been raised: 1193182/65536 =
18.2 times a second. Every 11932st tick, the time (also returned by
DateTime.Now) is updated. This means 1193182/11932 ~ 100 times a second.)


Armin

0 new messages