Solved

System.currentTimeMillis() resolution

Posted on 1998-12-07
25
311 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
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 

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
 
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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.

860 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