3
""" systimes() user and system timer implementations for use by
6
This module implements various different strategies for measuring
7
performance timings. It tries to choose the best available method
8
based on the platforma and available tools.
10
On Windows, it is recommended to have the Mark Hammond win32
11
package installed. Alternatively, the Thomas Heller ctypes
12
packages can also be used.
14
On Unix systems, the standard resource module provides the highest
15
resolution timings. Unfortunately, it is not available on all Unix
18
If no supported timing methods based on process time can be found,
19
the module reverts to the highest resolution wall-clock timer
20
instead. The system time part will then always be 0.0.
22
The module exports one public API:
26
Return the current timer values for measuring user and system
27
time as tuple of seconds (user_time, system_time).
29
Copyright (c) 2006, Marc-Andre Lemburg (mal@egenix.com). See the
30
documentation for further information on copyrights, or contact
31
the author. All Rights Reserved.
35
from __future__ import print_function
40
# Note: Please keep this module compatible to Python 1.5.2.
44
# * Add ctypes wrapper for new clock_gettime() real-time POSIX APIs;
45
# these will then provide nano-second resolution where available.
47
# * Add a function that returns the resolution of systimes()
48
# values, ie. systimesres().
51
### Choose an implementation
53
SYSTIMES_IMPLEMENTATION = None
54
USE_CTYPES_GETPROCESSTIMES = 'ctypes GetProcessTimes() wrapper'
55
USE_WIN32PROCESS_GETPROCESSTIMES = 'win32process.GetProcessTimes()'
56
USE_RESOURCE_GETRUSAGE = 'resource.getrusage()'
57
USE_PROCESS_TIME_CLOCK = 'time.clock() (process time)'
58
USE_WALL_TIME_CLOCK = 'time.clock() (wall-clock)'
59
USE_WALL_TIME_TIME = 'time.time() (wall-clock)'
61
if sys.platform[:3] == 'win':
69
# Use the wall-clock implementation time.clock(), since this
70
# is the highest resolution clock available on Windows
71
SYSTIMES_IMPLEMENTATION = USE_WALL_TIME_CLOCK
73
SYSTIMES_IMPLEMENTATION = USE_CTYPES_GETPROCESSTIMES
75
SYSTIMES_IMPLEMENTATION = USE_WIN32PROCESS_GETPROCESSTIMES
83
SYSTIMES_IMPLEMENTATION = USE_RESOURCE_GETRUSAGE
86
if SYSTIMES_IMPLEMENTATION is None:
87
# Check whether we can use time.clock() as approximation
92
if stop - start < 0.001:
93
# Looks like time.clock() is usable (and measures process
95
SYSTIMES_IMPLEMENTATION = USE_PROCESS_TIME_CLOCK
97
# Use wall-clock implementation time.time() since this provides
98
# the highest resolution clock on most systems
99
SYSTIMES_IMPLEMENTATION = USE_WALL_TIME_TIME
103
def getrusage_systimes():
104
return resource.getrusage(resource.RUSAGE_SELF)[:2]
106
def process_time_clock_systimes():
107
return (time.clock(), 0.0)
109
def wall_clock_clock_systimes():
110
return (time.clock(), 0.0)
112
def wall_clock_time_systimes():
113
return (time.time(), 0.0)
115
# Number of clock ticks per second for the values returned
116
# by GetProcessTimes() on Windows.
118
# Note: Ticks returned by GetProcessTimes() are 100ns intervals on
119
# Windows XP. However, the process times are only updated with every
120
# clock tick and the frequency of these is somewhat lower: depending
121
# on the OS version between 10ms and 15ms. Even worse, the process
122
# time seems to be allocated to process currently running when the
123
# clock interrupt arrives, ie. it is possible that the current time
124
# slice gets accounted to a different process.
126
WIN32_PROCESS_TIMES_TICKS_PER_SECOND = 1e7
128
def win32process_getprocesstimes_systimes():
129
d = win32process.GetProcessTimes(win32process.GetCurrentProcess())
130
return (d['UserTime'] / WIN32_PROCESS_TIMES_TICKS_PER_SECOND,
131
d['KernelTime'] / WIN32_PROCESS_TIMES_TICKS_PER_SECOND)
133
def ctypes_getprocesstimes_systimes():
134
creationtime = ctypes.c_ulonglong()
135
exittime = ctypes.c_ulonglong()
136
kerneltime = ctypes.c_ulonglong()
137
usertime = ctypes.c_ulonglong()
138
rc = ctypes.windll.kernel32.GetProcessTimes(
139
ctypes.windll.kernel32.GetCurrentProcess(),
140
ctypes.byref(creationtime),
141
ctypes.byref(exittime),
142
ctypes.byref(kerneltime),
143
ctypes.byref(usertime))
145
raise TypeError('GetProcessTimes() returned an error')
146
return (usertime.value / WIN32_PROCESS_TIMES_TICKS_PER_SECOND,
147
kerneltime.value / WIN32_PROCESS_TIMES_TICKS_PER_SECOND)
149
# Select the default for the systimes() function
151
if SYSTIMES_IMPLEMENTATION is USE_RESOURCE_GETRUSAGE:
152
systimes = getrusage_systimes
154
elif SYSTIMES_IMPLEMENTATION is USE_PROCESS_TIME_CLOCK:
155
systimes = process_time_clock_systimes
157
elif SYSTIMES_IMPLEMENTATION is USE_WALL_TIME_CLOCK:
158
systimes = wall_clock_clock_systimes
160
elif SYSTIMES_IMPLEMENTATION is USE_WALL_TIME_TIME:
161
systimes = wall_clock_time_systimes
163
elif SYSTIMES_IMPLEMENTATION is USE_WIN32PROCESS_GETPROCESSTIMES:
164
systimes = win32process_getprocesstimes_systimes
166
elif SYSTIMES_IMPLEMENTATION is USE_CTYPES_GETPROCESSTIMES:
167
systimes = ctypes_getprocesstimes_systimes
170
raise TypeError('no suitable systimes() implementation found')
174
""" Return the total time spent on the process.
176
This is the sum of user and system time as returned by
180
user, system = systimes()
187
for i in range(10000000):
191
print('Testing systimes() under load conditions')
197
print('differences:', (t1[0] - t0[0], t1[1] - t0[1]))
201
print('Testing systimes() under idle conditions')
207
print('differences:', (t1[0] - t0[0], t1[1] - t0[1]))
210
if __name__ == '__main__':
211
print('Using %s as timer' % SYSTIMES_IMPLEMENTATION)