Performance monitoring precision
Monitoring application performance is a primary use case of commons-monitoring. Java provides 2 timers implementation, as System.currentTimeMillis and System.nanoTime().
Those timers methods performances and real precision depends on the hardware, OS and JRE implementation.
MS Windows
Based on SUN technical documentation, both implementation precision depend on underlying hardware.
currentTimeMillis
uses a native windows low resolution timer, and for this reason is VERY quick (6 cycles), with a precision of only 10 to 15ms. Using this method as lower impacts on the application, but monitoring a process taking less than 15ms may produce elapsedTime=0 !nanoTime
uses Windows Performance API (when available) that is both hardware and version (and service pack) dependent (user timers, ACPI timers or CPU-level timers...). In most cases, this requires slow I/O instruction and result in microsecond accuracy. In better case requesting an on-chip timer requires ~100 cycles.
Both SUN JRE and Bea Jrockit implementation shows bad performances of nanoTime
on Windows, but the currentTimeMillis
precision is too limited for use as fine-grained performance counters.
Sun Solaris
On this platform, a quick & dirty bench [1] demonstrates both methods have comparable performances. No technical info on real precision, but nanoTime
would give the better one available.
Other systems
?? any info available ??
Java 1.3 / Java 1.4
backport-util-concurrent (used to backport commons-monitoring on pre-java5) provides an implementation of System.nanoTime
that delegates to currentTimeMillis
with unit conversion. On Sun JRE 1.4 it also uses an internal SUN performance package to get a better precision.
conclusion
Based on those informations, currentTimeMillis
- even with nice performances on Windows - cannot be used for fine-grained monitoring. In all cases nanoTime
provides the better time-counter available on the system, in terms of both precision and fiability
[2]
public class CurrentTimeMillisVsNanoTime { static int loops = 1000000; public static void main( String[] args ) { long time = System.nanoTime(); for ( int i = 0; i < loops; i++ ) { System.nanoTime(); } System.out.println( "System.nanoTime took : " + (System.nanoTime() - time) + "ns" ); time = System.nanoTime(); for ( int i = 0; i < loops; i++ ) { System.currentTimeMillis(); } System.out.println( "System.currentTimeMillis : " + (System.nanoTime() - time) + "ns" ); } }