ยปCore Development>Code coverage>Tools/pybench/systimes.py

Python code coverage for Tools/pybench/systimes.py

#countcontent
1n/a#!/usr/bin/env python
2n/a
3n/a""" systimes() user and system timer implementations for use by
4n/a pybench.
5n/a
6n/a This module implements various different strategies for measuring
7n/a performance timings. It tries to choose the best available method
8n/a based on the platform and available tools.
9n/a
10n/a On Windows, it is recommended to have the Mark Hammond win32
11n/a package installed. Alternatively, the Thomas Heller ctypes
12n/a packages can also be used.
13n/a
14n/a On Unix systems, the standard resource module provides the highest
15n/a resolution timings. Unfortunately, it is not available on all Unix
16n/a platforms.
17n/a
18n/a If no supported timing methods based on process time can be found,
19n/a the module reverts to the highest resolution wall-clock timer
20n/a instead. The system time part will then always be 0.0.
21n/a
22n/a The module exports one public API:
23n/a
24n/a def systimes():
25n/a
26n/a Return the current timer values for measuring user and system
27n/a time as tuple of seconds (user_time, system_time).
28n/a
29n/a Copyright (c) 2006, Marc-Andre Lemburg (mal@egenix.com). See the
30n/a documentation for further information on copyrights, or contact
31n/a the author. All Rights Reserved.
32n/a
33n/a"""
34n/a
35n/afrom __future__ import print_function
36n/a
37n/aimport time, sys
38n/a
39n/a#
40n/a# Note: Please keep this module compatible to Python 1.5.2.
41n/a#
42n/a# TODOs:
43n/a#
44n/a# * Add ctypes wrapper for new clock_gettime() real-time POSIX APIs;
45n/a# these will then provide nano-second resolution where available.
46n/a#
47n/a# * Add a function that returns the resolution of systimes()
48n/a# values, ie. systimesres().
49n/a#
50n/a
51n/a### Choose an implementation
52n/a
53n/aSYSTIMES_IMPLEMENTATION = None
54n/aUSE_CTYPES_GETPROCESSTIMES = 'ctypes GetProcessTimes() wrapper'
55n/aUSE_WIN32PROCESS_GETPROCESSTIMES = 'win32process.GetProcessTimes()'
56n/aUSE_RESOURCE_GETRUSAGE = 'resource.getrusage()'
57n/aUSE_PROCESS_TIME_CLOCK = 'time.clock() (process time)'
58n/aUSE_WALL_TIME_CLOCK = 'time.clock() (wall-clock)'
59n/aUSE_WALL_TIME_TIME = 'time.time() (wall-clock)'
60n/a
61n/aif sys.platform[:3] == 'win':
62n/a # Windows platform
63n/a try:
64n/a import win32process
65n/a except ImportError:
66n/a try:
67n/a import ctypes
68n/a except ImportError:
69n/a # Use the wall-clock implementation time.clock(), since this
70n/a # is the highest resolution clock available on Windows
71n/a SYSTIMES_IMPLEMENTATION = USE_WALL_TIME_CLOCK
72n/a else:
73n/a SYSTIMES_IMPLEMENTATION = USE_CTYPES_GETPROCESSTIMES
74n/a else:
75n/a SYSTIMES_IMPLEMENTATION = USE_WIN32PROCESS_GETPROCESSTIMES
76n/aelse:
77n/a # All other platforms
78n/a try:
79n/a import resource
80n/a except ImportError:
81n/a pass
82n/a else:
83n/a SYSTIMES_IMPLEMENTATION = USE_RESOURCE_GETRUSAGE
84n/a
85n/a# Fall-back solution
86n/aif SYSTIMES_IMPLEMENTATION is None:
87n/a # Check whether we can use time.clock() as approximation
88n/a # for systimes()
89n/a start = time.clock()
90n/a time.sleep(0.1)
91n/a stop = time.clock()
92n/a if stop - start < 0.001:
93n/a # Looks like time.clock() is usable (and measures process
94n/a # time)
95n/a SYSTIMES_IMPLEMENTATION = USE_PROCESS_TIME_CLOCK
96n/a else:
97n/a # Use wall-clock implementation time.time() since this provides
98n/a # the highest resolution clock on most systems
99n/a SYSTIMES_IMPLEMENTATION = USE_WALL_TIME_TIME
100n/a
101n/a### Implementations
102n/a
103n/adef getrusage_systimes():
104n/a return resource.getrusage(resource.RUSAGE_SELF)[:2]
105n/a
106n/adef process_time_clock_systimes():
107n/a return (time.clock(), 0.0)
108n/a
109n/adef wall_clock_clock_systimes():
110n/a return (time.clock(), 0.0)
111n/a
112n/adef wall_clock_time_systimes():
113n/a return (time.time(), 0.0)
114n/a
115n/a# Number of clock ticks per second for the values returned
116n/a# by GetProcessTimes() on Windows.
117n/a#
118n/a# Note: Ticks returned by GetProcessTimes() are 100ns intervals on
119n/a# Windows XP. However, the process times are only updated with every
120n/a# clock tick and the frequency of these is somewhat lower: depending
121n/a# on the OS version between 10ms and 15ms. Even worse, the process
122n/a# time seems to be allocated to process currently running when the
123n/a# clock interrupt arrives, ie. it is possible that the current time
124n/a# slice gets accounted to a different process.
125n/a
126n/aWIN32_PROCESS_TIMES_TICKS_PER_SECOND = 1e7
127n/a
128n/adef win32process_getprocesstimes_systimes():
129n/a d = win32process.GetProcessTimes(win32process.GetCurrentProcess())
130n/a return (d['UserTime'] / WIN32_PROCESS_TIMES_TICKS_PER_SECOND,
131n/a d['KernelTime'] / WIN32_PROCESS_TIMES_TICKS_PER_SECOND)
132n/a
133n/adef ctypes_getprocesstimes_systimes():
134n/a creationtime = ctypes.c_ulonglong()
135n/a exittime = ctypes.c_ulonglong()
136n/a kerneltime = ctypes.c_ulonglong()
137n/a usertime = ctypes.c_ulonglong()
138n/a rc = ctypes.windll.kernel32.GetProcessTimes(
139n/a ctypes.windll.kernel32.GetCurrentProcess(),
140n/a ctypes.byref(creationtime),
141n/a ctypes.byref(exittime),
142n/a ctypes.byref(kerneltime),
143n/a ctypes.byref(usertime))
144n/a if not rc:
145n/a raise TypeError('GetProcessTimes() returned an error')
146n/a return (usertime.value / WIN32_PROCESS_TIMES_TICKS_PER_SECOND,
147n/a kerneltime.value / WIN32_PROCESS_TIMES_TICKS_PER_SECOND)
148n/a
149n/a# Select the default for the systimes() function
150n/a
151n/aif SYSTIMES_IMPLEMENTATION is USE_RESOURCE_GETRUSAGE:
152n/a systimes = getrusage_systimes
153n/a
154n/aelif SYSTIMES_IMPLEMENTATION is USE_PROCESS_TIME_CLOCK:
155n/a systimes = process_time_clock_systimes
156n/a
157n/aelif SYSTIMES_IMPLEMENTATION is USE_WALL_TIME_CLOCK:
158n/a systimes = wall_clock_clock_systimes
159n/a
160n/aelif SYSTIMES_IMPLEMENTATION is USE_WALL_TIME_TIME:
161n/a systimes = wall_clock_time_systimes
162n/a
163n/aelif SYSTIMES_IMPLEMENTATION is USE_WIN32PROCESS_GETPROCESSTIMES:
164n/a systimes = win32process_getprocesstimes_systimes
165n/a
166n/aelif SYSTIMES_IMPLEMENTATION is USE_CTYPES_GETPROCESSTIMES:
167n/a systimes = ctypes_getprocesstimes_systimes
168n/a
169n/aelse:
170n/a raise TypeError('no suitable systimes() implementation found')
171n/a
172n/adef processtime():
173n/a
174n/a """ Return the total time spent on the process.
175n/a
176n/a This is the sum of user and system time as returned by
177n/a systimes().
178n/a
179n/a """
180n/a user, system = systimes()
181n/a return user + system
182n/a
183n/a### Testing
184n/a
185n/adef some_workload():
186n/a x = 0
187n/a for i in range(10000000):
188n/a x = x + 1
189n/a
190n/adef test_workload():
191n/a print('Testing systimes() under load conditions')
192n/a t0 = systimes()
193n/a some_workload()
194n/a t1 = systimes()
195n/a print('before:', t0)
196n/a print('after:', t1)
197n/a print('differences:', (t1[0] - t0[0], t1[1] - t0[1]))
198n/a print()
199n/a
200n/adef test_idle():
201n/a print('Testing systimes() under idle conditions')
202n/a t0 = systimes()
203n/a time.sleep(1)
204n/a t1 = systimes()
205n/a print('before:', t0)
206n/a print('after:', t1)
207n/a print('differences:', (t1[0] - t0[0], t1[1] - t0[1]))
208n/a print()
209n/a
210n/aif __name__ == '__main__':
211n/a print('Using %s as timer' % SYSTIMES_IMPLEMENTATION)
212n/a print()
213n/a test_workload()
214n/a test_idle()