> For the complete documentation index, see [llms.txt](https://docs.rumi.systems/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rumi.systems/performance/benchmark-suite/modules/time-module.md).

# Time Module

The Time module benchmarks the overhead of Rumi's time acquisition APIs. Time acquisition is a critical operation in high-performance systems, and this benchmark helps quantify the cost of different time sources.

## Overview

Rumi provides multiple time sources optimized for different use cases:

* **Native Time**: Uses native (JNI) calls for high-resolution wall-clock time
* **Epoch Time**: Uses pure Java implementation for wall-clock time
* **System.nanoTime()**: JVM's monotonic time source

This benchmark measures the overhead (in nanoseconds) of acquiring time from each source.

## Test Program

**Class**: `com.neeve.perf.time.Benchmark`

The benchmark:

1. Warms up with 10,000 time acquisitions
2. Measures 100,000,000 time acquisitions
3. Reports average overhead per call in nanoseconds
4. Supports concurrent execution across multiple threads

## Time Sources

### Native Time

Uses JNI to call native high-resolution clock:

```bash
java -Dnv.time.usenative=true -cp "libs/*" com.neeve.perf.time.Benchmark --mode native
```

**Characteristics**:

* Highest resolution (typically nanosecond precision)
* Slightly higher overhead due to JNI call
* Wall-clock time (can go backwards on NTP adjustments)

**Use When**: You need highest resolution time and can afford JNI overhead

### Epoch Time

Uses pure Java implementation:

```bash
java -Dnv.time.usenative=false -cp "libs/*" com.neeve.perf.time.Benchmark --mode epoch
```

**Characteristics**:

* Pure Java (no JNI overhead)
* Lower overhead than native
* Wall-clock time (can go backwards on NTP adjustments)
* Resolution depends on JVM (typically microsecond precision)

**Use When**: You need wall-clock time with lower overhead

### System.nanoTime()

Uses JVM's monotonic time source:

```bash
java -cp "libs/*" com.neeve.perf.time.Benchmark --mode nano
```

**Characteristics**:

* Lowest overhead
* Monotonic (never goes backwards)
* NOT wall-clock time (arbitrary epoch)
* High resolution

**Use When**: You need to measure elapsed time or durations

## Command-Line Parameters

| Parameter | Description                                                 |
| --------- | ----------------------------------------------------------- |
| `-m`      | Time source: `native`, `epoch`, or `nano` (default: native) |
| `-t`      | Number of concurrent threads (default: 1)                   |
| `-h`      | Print usage information                                     |

## Running the Benchmark

### Basic Usage

```bash
# Extract distribution
tar xvf nvx-perf-time-{version}-dist-linux-x86-64.tar.gz
cd nvx-perf-time-{version}

# Run benchmark with native time
$JAVA_HOME/bin/java -cp "libs/*" com.neeve.perf.time.Benchmark --mode native
```

### Test Native Time

```bash
$JAVA_HOME/bin/java -cp "libs/*" com.neeve.perf.time.Benchmark -m native
```

**Example Output**:

```
USING UtlTime.now() [NATIVE TIME IS ENABLED]
[tid 1] Time overhead is 35 nanos
```

### Test Epoch Time

```bash
$JAVA_HOME/bin/java -cp "libs/*" com.neeve.perf.time.Benchmark -m epoch
```

**Example Output**:

```
USING UtlTime.now() [NATIVE TIME IS DISABLED]
[tid 1] Time overhead is 28 nanos
```

### Test System.nanoTime()

```bash
$JAVA_HOME/bin/java -cp "libs/*" com.neeve.perf.time.Benchmark -m nano
```

**Example Output**:

```
USING System.nanoTime()
[tid 1] Time overhead is 22 nanos
```

### Test with Multiple Threads

```bash
$JAVA_HOME/bin/java -cp "libs/*" com.neeve.perf.time.Benchmark -m native -t 4
```

**Example Output**:

```
USING UtlTime.now() [NATIVE TIME IS ENABLED]
[tid 10] Time overhead is 37 nanos
[tid 11] Time overhead is 36 nanos
[tid 12] Time overhead is 38 nanos
[tid 13] Time overhead is 35 nanos
```

## Interpreting Results

The benchmark reports the average overhead per time acquisition in **nanoseconds**.

### Typical Results (Linux x86-64)

| Time Source       | Single Thread | Multiple Threads | Resolution  |
| ----------------- | ------------- | ---------------- | ----------- |
| System.nanoTime() | \~20-25ns     | \~20-25ns        | Nanosecond  |
| Epoch Time        | \~25-30ns     | \~25-30ns        | Microsecond |
| Native Time       | \~30-40ns     | \~30-40ns        | Nanosecond  |

### Performance Considerations

1. **Absolute Overhead**:
   * All time sources have sub-40ns overhead
   * Overhead is negligible for most applications
   * Matters most in tight loops or very low latency paths
2. **Contention**:
   * Time acquisition overhead typically doesn't increase with thread count
   * Modern CPUs have per-core time sources
3. **Use Case Selection**:
   * **Latency Tracking**: Use native or epoch time for wall-clock timestamps
   * **Duration Measurement**: Use System.nanoTime() for elapsed time
   * **Hot Paths**: Use epoch time for balance of overhead and resolution

## Best Practices

### For Latency Measurement

Use wall-clock time (native or epoch) to timestamp events:

```java
// Timestamp incoming message
long receiveTime = UtlTime.now();

// Process message...

// Timestamp outgoing message
long sendTime = UtlTime.now();

// Calculate latency
long latency = sendTime - receiveTime;
```

### For Duration Measurement

Use System.nanoTime() for elapsed time:

```java
// Start timing
long startNanos = System.nanoTime();

// Do work...

// Calculate duration
long durationNanos = System.nanoTime() - startNanos;
```

### For High-Frequency Calls

If time acquisition is in a critical path called millions of times per second, prefer epoch time:

```java
// Configure at startup
System.setProperty("nv.time.usenative", "false");

// In critical path
long timestamp = UtlTime.now(); // Uses epoch time (lower overhead)
```

## System Properties

| Property            | Values     | Description                                |
| ------------------- | ---------- | ------------------------------------------ |
| `nv.time.usenative` | true/false | Enable/disable native time (default: true) |

## Next Steps

* Review [AEP Module](/performance/benchmark-suite/modules/aep-module.md) to see time usage in end-to-end benchmarks
* Explore [Serialization Module](/performance/benchmark-suite/modules/serialization-module.md) for message encoding benchmarks
* Return to [Benchmark Suite](/performance/benchmark-suite.md) for other modules


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.rumi.systems/performance/benchmark-suite/modules/time-module.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
