Solved

System.currentTimeMillis() resolution

Posted on 1998-12-07
25
302 Views
Last Modified: 2012-08-13
I have the following problem -

I am trying to measure how much time has passed from one point in my code to another.
I take the time before the relevant part of the code starts with "long l = System.currentTimeMillis()" and at the end of the code I subtract l from the new System.currentTimeMillis().

This happens many times in my program. Most of the time the subtraction gives 0, and rarely it gives 10.
I assume that the resolution of "System.currentTimeMillis()" is 10MS (anything under 5 is rounded to 0, right?).

Because of the above problem, I get very inaccurate results.

Any suggestions ?

(I already tried multiplying the result by 1000, or converting it to double - no good).
0
Comment
Question by:theGrayPilgrim
  • 9
  • 7
  • 6
  • +2
25 Comments
 
LVL 2

Expert Comment

by:vendrig
ID: 1228889
I had the same experience, same diagnosis. BUT: I think it's platform-dependent! 10 ms on Wintel, 1 ms on Unix.
0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228890
of course time measurment is platform dependent.

the best solution is not to multiple the result by 1000, but to run your code 1000 times !!!

(take a look at
http://www.experts-exchange.com/topics/comp/lang/java/Q.10102586
"Timing integer sorts")

hope this helps
  heyhey
0
 
LVL 2

Expert Comment

by:vendrig
ID: 1228891
Actually, it's a good idea to implement heyhey's suggestion anyhow (if your code allows), because one measurement often is not accurate enough. Even if it seems exact to the nanosecond.
0
 

Author Comment

by:theGrayPilgrim
ID: 1228892
heyhey and vendrik -

I am working under WinNT, which explains the 10MS resolution.
However heyhey, I can't use your solution -

The actual problem is this - I have a socket, every now and again I read a chunk of data from the socket. The time between 2 consecutive reads is different each time - it can be a few MS or a few seconds.
I am trying to sum up all the bytes I read, sum up the time it took me to read them, and than calculate my Bandwidth in bytes/sec.

Because in many cases the chunk of data is small (24 bytes), if I measure the time before and after the read loop, I get
"after" - "before" = 0.

The suggested answer obviously can't be implemented here...

Any other suggestions ?
0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228893
:)

the only thing i can suggest is
long milis = after - before;
if (milis == 0) milis = 5; // :)

or maybe you can measure the time when you don't receive data and substract it from the total time ??
0
 

Author Comment

by:theGrayPilgrim
ID: 1228894
heyhey thanks,

what you suggest is more or less what I do.
What I actually do is this -

long milis = after - before;
if (milis == 0) milis = numberOfByteToRead/5;

This is the best solution I could come up with, but when you think about it, it's actually pretty stupid, because by doing this I 'decide' that my bandwidth is 5Kb/sec when my overall purpuse checking what my bandwidth is ...  :)

I'm still opened to suggestions...
0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228895
maybe this is better solution
if (milis == 0) milis = numberOfByteToRead * curBytesPerSecond;
// instead of 5Kb/sec use the current estimated bandwidth ...

what about measuring the time when you don't receive data ???
0
 

Author Comment

by:theGrayPilgrim
ID: 1228896
Since in most cases the time in which I read data sums up to 0, I assume that the time where I don't read data will be -

"allTheTime" - "TimeOfRead" = "allTheTime".

(What I mean is that if I will measure the time where I don't read, it will sum up to the entire time span).

Don't you think that will be the case? Otherwise, some time will be "lost", right?

The problem with your other suggestion is that in some cases, if I start with reading small chunks of data I will not have any valid "curBytesPerSecond" to rely upon.

I appreciate your efforts heyhey :) .

0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228897
:)

>> Don't you think that will be the case? Otherwise, some time will be "lost", right?
probably yes :)

I have one last (again almost stupid :) suggestion - you don't use the temporary value of "curBytesPerSecond", but the "total one" - but that is equvalent of ignoring all the small chunks of data and measuring "bytesPerSecond" using only statistics from the big chunks ...

probably native methods can work (if you need it to work only on NT) - i have to check what is the (native) time resolution on NT ...
0
 

Author Comment

by:theGrayPilgrim
ID: 1228898
The only problem with your last suggestion is that I don't know in advance the size of the data chunks. It is possible that they will ALL be small, and then I will but stuck.

My applet is required to work on all platforms. It might however be a good idea to check under which platform I am running, and put some platform dependent code in my applet. It is something I have never done before, but since I see no better solution, I might not have any choice.
0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228899
>> ... put some platform dependent code in my applet...

it seems that you there is no Java solution ... and using in Native code in applets ... hmmm ... i don't thing this is possible at all (you CAN'T use native code from unsigned applet, and probably you can't use native code even from signed applet - just a technology problem)

so, i am afraid there is no solution of your problem ...

(but it will be interesting for us to see the your partialy solution ...)

best regards
  heyhey
0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228900
oh, so much typos :(( sorry
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 8

Expert Comment

by:diakov
ID: 1228901
Why don't you implement a native method startTimer() and stopTimer(). You have to additionally build a shared library with these methods and then use the appropriate API calls to measure time.

Cheers,
  Nik
0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228902
diakov:

just curious ... have you ever called native methods from APPLET ?
0
 
LVL 8

Expert Comment

by:diakov
ID: 1228903
To 'heyhey_':

Yes. Why, can't you do it?

Look at
http://www.javaworld.com/javaworld/jw-10-1998/jw-10-apptowin32.html
where you'll find an article:
"Escape the sandbox: Access native methods from an applet"

Cheers,
  nik
0
 

Author Comment

by:theGrayPilgrim
ID: 1228904
diakov,

I am not sure if I follow you - if I implement a native method, how do I invoke it on the users machine as a part of an applet?
Also, I will have to implement a different set of native methods for each different platform, won't I ?
(I've never tried invoking native methods from an applet. Maybe I should have a look at that URL you mention above ...)

BTW - do you know if the resolution of the System.time is better when using native code?

TIA,

Roy.
0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228905
hmm, interesting ...
one has so much things to learn ...
thanks diakov :)

theGrayPilgrim:
it seems that at least Windows platform does not support such a low timer resolution ...

'Remarks
The following table describes the resolution of the system timer.
System Resolution
Windows NT 3.5 and later <-> The system timer runs at approximately 10ms.
Windows NT 3.1 <-> The system timer runs at approximately 16ms.
Windows 95 and later <-> The system timer runs at approximately 55ms.'

0
 
LVL 8

Expert Comment

by:diakov
ID: 1228906
'theGrayPilgrim',
I mean, that if the Java resolution is not enough you can always go native, write the code for getting the best time there and return it to the Java environment.

Do have a look to the URL.

to heyhey_:

There are some articles on the MSDN network available through the
web, that show how to implement High Resolution Timers.

Have a look.

The methods that would do are win32 api:
QueryPerformanceFrequency and QueryPerformanceCounter
But, again this is native and Windows. On UNIX may be there is another solution to make a high resolution timer.

Cheers,
  Nik


0
 
LVL 8

Expert Comment

by:diakov
ID: 1228907
http://premium.microsoft.com/msdn/library/sdkdoc/winbase/timers_827m.htm

is the link with the article about the high performance counters.

you can do 50000 times in second if you wish.

Nik.
0
 

Author Comment

by:theGrayPilgrim
ID: 1228908
diakov,

Sorry I had to reject your answer. I did it not because the solution you supplied is not good and valid, but because we can't use it, for the following reason -

The document "Escape the sandbox..." says -

"...This method causes the browser to display a dialog, ...
In the case below, the user will be asked to allow access to the local filesystem..."

Being a commercial company (www.emblaze.com), Our marketing department cannot allow such a message. The average user, seeing such a security alert, will deny the applet any privilages.

Although at this point I'm pretty pesimistic, I still hope some better solution might show up... :)
0
 
LVL 8

Expert Comment

by:diakov
ID: 1228909
When you want to sign an applet, this dialog appears only once per certificate. It is inevitable and yet necessary since you install a browser extension (native code) on the machine and need filewrite privileges. Also some other. You can also handle the rejection of the user and implement different explanatory interface.

I still think if you do not have enough resolution on the timer you need the native soulution of WIN32 API, since it is powerfull enough. But if you decide to go for it, you need to istinguish the OS, and to install the correct native code library. Java has system properties that help doing this.

But anyway, no problem with the rejection. As the etiquette says, an answer counts only if you learn something new from it and can make use of it.

Cheers,
  Nik
0
 
LVL 4

Expert Comment

by:evijay
ID: 1228910
Hi,

1 millisecond is quite a big time. Java on winnt uses the windows 32 API, GetSystemTime to get the time for System.currentTimeMilliseconds.

what I suggest is send large chunks of data whose data transfer may take some 1 second or so (Send about 30 KB of data), receive it on the other end all in one chunk and then call System.currentTimeMillisecond. Even if you write a C program which uses GetSystemTime() win32 API you will find that to get a  1 millisecond delay, you need to do a lot of processing in your testing loop. You can imagine the speed of our processor which is 300 MHz meaning, each clock tick is about 1/300MHz. The speed of network connection is 10 MHz and all this indicate that they are quite fast. You can accurately estimate your bandwidth only by sending large chunks of data not just 2 or three bytes.

Regards
Vijay

0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228911
>> ....  you need the native soulution of WIN32 API, ...

if you need only WIn32 solution, you'd better use ActiveX (i still don't think that Win OS has such a finer granularity ...)

it seems that there is no pire Java solution ... and i don't think that you can write pieces of native code for all available OSes ..

best regards
  heyhey
P.S. sorry, theGrayPilgrim .. but most OSes nowadays don't support the low time resolution you need ...
0
 

Author Comment

by:theGrayPilgrim
ID: 1228912
diakov and heyhey ,

I appears that there is no Java solution for my problem. Eventually, I had to force a minimal data chunk so that I won't get zeroes - which is something I didn't want to do.

Anyway, there is no point in having this question in the 'waiting for answer' queue, so -

heyhey - thanks for your efforts, I really appreciate it... :)

diakov - since the article you mentioned might be useful for me in the future, if you post an answer to this question I will accept it.

Roy.
0
 
LVL 8

Accepted Solution

by:
diakov earned 180 total points
ID: 1228913
Thanks.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now