Skip to content

Commit 8a48496

Browse files
committed
[GR-20022] Add new time functions with nanosecond resolution.
PullRequest: graalpython/761
2 parents 126d2c6 + 177f289 commit 8a48496

File tree

1 file changed

+60
-1
lines changed

1 file changed

+60
-1
lines changed

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

Lines changed: 60 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() {
@@ -182,6 +183,35 @@ public double time() {
182183
}
183184
}
184185

186+
// time.time_ns()
187+
@Builtin(name = "time_ns", minNumOfPositionalArgs = 0, doc = "Similar to time() but returns time as an integer number of nanoseconds since the epoch.")
188+
@GenerateNodeFactory
189+
public abstract static class PythonTimeNsNode extends PythonBuiltinNode {
190+
191+
/**
192+
* The maximum date, which are systems able to handle is 2262 04 11. This corresponds to the
193+
* 64 bit long.
194+
*
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
206+
// jdk
207+
// JKD 1.8 the resolution is usually miliseconds (for example 1576081173486000000)
208+
// From JDK 9 including JDK 11 the resolution is usually microseconds (for example
209+
// 1576082578022393000)
210+
// To obtain really nanosecond resulution we have to fake the nanoseconds
211+
return now.getEpochSecond() * 1000000000L + now.getNano();
212+
}
213+
}
214+
185215
// time.monotonic()
186216
@Builtin(name = "monotonic", minNumOfPositionalArgs = 0)
187217
@GenerateNodeFactory
@@ -190,15 +220,44 @@ public abstract static class PythonMonotonicNode extends PythonBuiltinNode {
190220
@Specialization
191221
@TruffleBoundary
192222
public double time() {
223+
return System.nanoTime() / 1000000000D;
224+
}
225+
}
226+
227+
// time.monotonic_ns()
228+
@Builtin(name = "monotonic_ns", minNumOfPositionalArgs = 0, doc = "Similar to monotonic(), but return time as nanoseconds.")
229+
@GenerateNodeFactory
230+
public abstract static class PythonMonotonicNsNode extends PythonBuiltinNode {
231+
232+
@Specialization
233+
@TruffleBoundary
234+
public long time() {
193235
return System.nanoTime();
194236
}
195237
}
196238

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

260+
// TODO time.clock in 3.8 is removed in 3.5 is deprecated
202261
// time.clock()
203262
@Builtin(name = "clock", minNumOfPositionalArgs = 0)
204263
@GenerateNodeFactory

0 commit comments

Comments
 (0)