Some reader favorites:
EJB fundamentals and session beans
Create a scrollable virtual desktop in Swing
Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API
January 10, 2003
Is the resolution of System.currentTimeMillis() enough for profiling Java code?
Evaluating the actual resolution is easy enough. The following code snippet,
public static void main (String [] args)
{
// JIT/hotspot warmup:
for (int r = 0; r < 3000; ++ r) System.currentTimeMillis ();
long time = System.currentTimeMillis (), time_prev = time;
for (int i = 0; i < 5; ++ i)
{
// Busy wait until system time changes:
while (time == time_prev)
time = System.currentTimeMillis ();
System.out.println ("delta = " + (time - time_prev) + " ms");
time_prev = time;
}
}
when run in JDK 1.4.1 on a Windows 2000 system, produces the following:
delta = 10 ms delta = 10 ms delta = 10 ms delta = 10 ms delta = 10 ms
You will discover that results vary based on your platform. Java developers on Linux enjoy 1-millisecond (ms) resolution,
while Windows 98 users suffer with 50-ms resolution. In most cases, the actual resolution has nothing to do with the fact
that System.currenTimeMillis()'s return value is current time in milliseconds.
Java developer forums are full of arguments about whether a particular language trick offers performance advantages, with
developers presenting "proofs" based on System.currentTimeMilllis() returning "0 ms versus 10 ms" for some new way of implementing a particular code paradigm. You should see now that this is
naive at best. On the system used above, System.currentTimeMilllis() is suitable only for profiling relatively long-lasting (100 ms and longer) operations. If you cannot loop over code being
profiled a sufficient number of times to get the cumulative execution time in this range, you need another approach.
Occasionally, you can find alternative suggestions based on Object.wait(long) or Thread.sleep(long) methods. Unfortunately, these are not good alternatives either, as the following code demonstrates:
public static void main (String [] args) throws Exception
{
final DecimalFormat format = new DecimalFormat ();
format.setMinimumFractionDigits (3);
format.setMaximumFractionDigits (3);
// Create an ITimer using the Factory class:
final ITimer timer = TimerFactory.newTimer ();
// JIT/hotspot warmup:
for (int i = 0; i < 3000; ++ i)
{
timer.start ();
timer.stop ();
timer.getDuration ();
timer.reset ();
}
final Object lock = new Object (); // used by monitor.wait() below
for (int i = 0; i < 5; ++ i)
{
timer.start ();
// Uncomment various lines below to see the resolution
// offered by other Java time-related methods:
synchronized (lock) { lock.wait (1); }
//Thread.currentThread ().sleep (1);
//Thread.currentThread ().sleep (0, 500);
//Thread.currentThread ().join (1);
timer.stop ();
System.out.println ("duration = "
+ format.format (timer.getDuration ()) + " ms");
timer.reset ();
}
}
On the same system used for the first experiment, this results in:
duration = 5.678 ms duration = 7.313 ms duration = 14.805 ms duration = 15.078 ms duration = 15.105 ms
(You might be wondering about the mysterious ITimer timer object above. I will explain this shortly. For now, realize that I, of course, could not use System.currenTimeMillis() to measure resolution of anything that might be better than that method.)
Free Download - 5 Minute Product Review. When slow equals Off: Manage the complexity of Web applications - Symphoniq
![]()
Free Download - 5 Minute Product Review. Realize the benefits of real user monitoring in less than an hour. - Symphoniq