Link to home
Start Free TrialLog in
Avatar of theGrayPilgrim
theGrayPilgrim

asked on

System.currentTimeMillis() resolution

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).
Avatar of vendrig
vendrig

I had the same experience, same diagnosis. BUT: I think it's platform-dependent! 10 ms on Wintel, 1 ms on Unix.
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
https://www.experts-exchange.com/topics/comp/lang/java/Q.10102586
"Timing integer sorts")

hope this helps
  heyhey
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.
Avatar of theGrayPilgrim

ASKER

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 ?
:)

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 ??
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...
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 ???
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 :) .

:)

>> 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 ...
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.
>> ... 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
oh, so much typos :(( sorry
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
diakov:

just curious ... have you ever called native methods from APPLET ?
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
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.
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.'

'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


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.
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... :)
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
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

>> ....  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 ...
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.
ASKER CERTIFIED SOLUTION
Avatar of diakov
diakov

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial