Skip to content

Commit

Permalink
Perf optimization (disable system calls to get time)
Browse files Browse the repository at this point in the history
In benchmarks where metrics are not required, the system calls to get time (System.currentTimeMillis()) may introduce an unnecessary overhead.
This change enables such benchmarks to disable these system calls to get metric durations.

It is important to note that apart from these system time calls metric generation does not have an object allocation overhead. So, for any benchmarks the metrics infrastructure should not pose much overhead.
  • Loading branch information
Nitesh Kant committed Jul 4, 2014
1 parent da12298 commit 12b05d9
Showing 1 changed file with 41 additions and 1 deletion.
42 changes: 41 additions & 1 deletion rx-netty/src/main/java/io/reactivex/netty/metrics/Clock.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.reactivex.netty.metrics;

import java.util.concurrent.TimeUnit;
Expand All @@ -34,10 +35,24 @@
*/
public class Clock {

/**
* The value returned by all static methods in this class, viz.,
* <ul>
<li>{@link #newStartTime(TimeUnit)}</li>
<li>{@link #newStartTimeMillis()}</li>
<li>{@link #onEndMillis(long)}</li>
<li>{@link #onEnd(long, TimeUnit)}</li>
</ul>
* after calling {@link #disableSystemTimeCalls()}
*/
public static final long SYSTEM_TIME_DISABLED_TIME = -1;

private final long startTimeMillis = System.currentTimeMillis();
private long endTimeMillis = -1;
private long durationMillis = -1;

private static volatile boolean disableSystemTimeCalls;

/**
* Stops this clock. This method is idempotent, so, after invoking this method, the duration of the clock is
* immutable. Hence, you can call this method multiple times with no side-effects.
Expand Down Expand Up @@ -92,18 +107,40 @@ public boolean isRunning() {
return -1 != durationMillis;
}

/**
* An optimization hook for low level benchmarks which will make any subsequent calls to
* <ul>
<li>{@link #newStartTime(TimeUnit)}</li>
<li>{@link #newStartTimeMillis()}</li>
<li>{@link #onEndMillis(long)}</li>
<li>{@link #onEnd(long, TimeUnit)}</li>
</ul>
* will start returning {@link #SYSTEM_TIME_DISABLED_TIME}. This essentially means that instead of calling
* {@link System#currentTimeMillis()} these methods will use {@link #SYSTEM_TIME_DISABLED_TIME}
*/
public static void disableSystemTimeCalls() {
disableSystemTimeCalls = true;
}

public static long newStartTimeMillis() {
return System.currentTimeMillis();
return disableSystemTimeCalls ? SYSTEM_TIME_DISABLED_TIME : System.currentTimeMillis();
}

public static long newStartTime(TimeUnit timeUnit) {
if (disableSystemTimeCalls) {
return SYSTEM_TIME_DISABLED_TIME;
}

if (TimeUnit.MILLISECONDS == timeUnit) {
return newStartTimeMillis();
}
return timeUnit.convert(newStartTimeMillis(), TimeUnit.MILLISECONDS);
}

public static long onEnd(long startTime, TimeUnit timeUnit) {
if (disableSystemTimeCalls) {
return SYSTEM_TIME_DISABLED_TIME;
}
if (TimeUnit.MILLISECONDS == timeUnit) {
return onEndMillis(startTime);
}
Expand All @@ -112,6 +149,9 @@ public static long onEnd(long startTime, TimeUnit timeUnit) {
}

public static long onEndMillis(long startTimeMillis) {
if (disableSystemTimeCalls) {
return SYSTEM_TIME_DISABLED_TIME;
}
return System.currentTimeMillis() - startTimeMillis;
}
}

0 comments on commit 12b05d9

Please sign in to comment.