Skip to content

Commit 559e862

Browse files
committed
[GR-20022] Add new time functions with nanosecond resolution.
1 parent cd5f4ad commit 559e862

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
@CoreFunctions(defineModule = "time")
7272
public final class TimeModuleBuiltins extends PythonBuiltins {
7373
private static final int DELAY_NANOS = 10;
74+
private static final long PERF_COUNTER_START = TruffleOptions.AOT ? 0 : System.nanoTime();
7475

7576
@Override
7677
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
@@ -181,6 +182,34 @@ public double time() {
181182
return timeSeconds();
182183
}
183184
}
185+
186+
// time.time_ns()
187+
@Builtin(name = "time_ns", minNumOfPositionalArgs = 0,
188+
doc = "Similar to time() but returns time as an integer number of nanoseconds since the epoch.")
189+
@GenerateNodeFactory
190+
public abstract static class PythonTimeNsNode extends PythonBuiltinNode {
191+
192+
/**
193+
* The maximum date, which are systems able to handle is 2262 04 11. This
194+
* corresponds to the 64 bit long.
195+
* @return
196+
*/
197+
@Specialization
198+
public long time() {
199+
return timeNanoSeconds();
200+
}
201+
202+
@TruffleBoundary
203+
private static long timeNanoSeconds() {
204+
Instant now = Instant.now();
205+
// From java we are not able to obtain the nano seconds resolution. It depends on the jdk
206+
// JKD 1.8 the resolution is usually miliseconds (for example 1576081173486000000)
207+
// From JDK 9 including JDK 11 the resolution is usually microseconds (for example 1576082578022393000)
208+
// To obtain really nanosecond resulution we have to fake the nanoseconds
209+
return now.getEpochSecond() * 1000000000L + now.getNano();
210+
}
211+
}
212+
184213

185214
// time.monotonic()
186215
@Builtin(name = "monotonic", minNumOfPositionalArgs = 0)
@@ -190,15 +219,44 @@ public abstract static class PythonMonotonicNode extends PythonBuiltinNode {
190219
@Specialization
191220
@TruffleBoundary
192221
public double time() {
222+
return System.nanoTime() / 1000000000D;
223+
}
224+
}
225+
226+
// time.monotonic_ns()
227+
@Builtin(name = "monotonic_ns", minNumOfPositionalArgs = 0, doc = "Similar to monotonic(), but return time as nanoseconds.")
228+
@GenerateNodeFactory
229+
public abstract static class PythonMonotonicNsNode extends PythonBuiltinNode {
230+
231+
@Specialization
232+
@TruffleBoundary
233+
public long time() {
193234
return System.nanoTime();
194235
}
195236
}
196237

197238
@Builtin(name = "perf_counter", minNumOfPositionalArgs = 0)
198239
@GenerateNodeFactory
199-
public abstract static class PythonPerfCounterNode extends PythonClockNode {
240+
public abstract static class PythonPerfCounterNode extends PythonBuiltinNode {
241+
@Specialization
242+
@TruffleBoundary
243+
public double counter() {
244+
return (System.nanoTime() - PERF_COUNTER_START) / 1000_000_000.0;
245+
}
246+
}
247+
248+
@Builtin(name = "perf_counter_ns", minNumOfPositionalArgs = 0)
249+
@GenerateNodeFactory
250+
public abstract static class PythonPerfCounterNsNode extends PythonBuiltinNode {
251+
252+
@Specialization
253+
@TruffleBoundary
254+
public long counter() {
255+
return System.nanoTime() - PERF_COUNTER_START;
256+
}
200257
}
201258

259+
// TODO time.clock in 3.8 is removed in 3.5 is deprecated
202260
// time.clock()
203261
@Builtin(name = "clock", minNumOfPositionalArgs = 0)
204262
@GenerateNodeFactory

0 commit comments

Comments
 (0)