0
0
mirror of https://github.com/python/cpython.git synced 2024-12-01 11:15:56 +01:00
cpython/Tools/pybench/systimes.py
Guido van Rossum 486364b821 Merged revisions 56020-56124 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/p3yk

................
  r56037 | georg.brandl | 2007-06-19 05:33:20 -0700 (Tue, 19 Jun 2007) | 2 lines

  Patch #1739659: don't slice dict.keys() in pydoc.
................
  r56060 | martin.v.loewis | 2007-06-21 13:00:02 -0700 (Thu, 21 Jun 2007) | 2 lines

  Regenerate to add True, False, None.
................
  r56069 | neal.norwitz | 2007-06-21 22:31:56 -0700 (Thu, 21 Jun 2007) | 1 line

  Get the doctest working again after adding None, True, and False as kewyords.
................
  r56070 | neal.norwitz | 2007-06-21 23:25:33 -0700 (Thu, 21 Jun 2007) | 1 line

  Add space to error message.
................
  r56071 | neal.norwitz | 2007-06-21 23:40:04 -0700 (Thu, 21 Jun 2007) | 6 lines

  Get pybench working, primarily
   * Use print function
   * Stop using string module
   * Use sorted instead of assuming dict methods return lists
   * Convert range result to a list
................
  r56089 | collin.winter | 2007-06-26 10:31:48 -0700 (Tue, 26 Jun 2007) | 1 line

  Fix AttributeError in distutils/dir_util.py.
................
  r56124 | guido.van.rossum | 2007-06-29 18:04:31 -0700 (Fri, 29 Jun 2007) | 30 lines

  Merged revisions 56014-56123 via svnmerge from
  svn+ssh://pythondev@svn.python.org/python/trunk

  ........
    r56019 | lars.gustaebel | 2007-06-18 04:42:11 -0700 (Mon, 18 Jun 2007) | 2 lines

    Added exclude keyword argument to the TarFile.add() method.
  ........
    r56023 | lars.gustaebel | 2007-06-18 13:05:55 -0700 (Mon, 18 Jun 2007) | 3 lines

    Added missing \versionchanged tag for the new exclude
    parameter.
  ........
    r56038 | georg.brandl | 2007-06-19 05:36:00 -0700 (Tue, 19 Jun 2007) | 2 lines

    Bug #1737864: allow empty message in logging format routines.
  ........
    r56040 | georg.brandl | 2007-06-19 05:38:20 -0700 (Tue, 19 Jun 2007) | 2 lines

    Bug #1739115: make shutil.rmtree docs clear wrt. file deletion.
  ........
    r56084 | georg.brandl | 2007-06-25 08:21:23 -0700 (Mon, 25 Jun 2007) | 2 lines

    Bug #1742901: document None behavior of shlex.split.
  ........
    r56091 | georg.brandl | 2007-06-27 07:09:56 -0700 (Wed, 27 Jun 2007) | 2 lines

    Fix a variable name in winreg docs.
  ........
................
2007-06-30 05:01:58 +00:00

212 lines
6.5 KiB
Python

#!/usr/bin/env python
""" systimes() user and system timer implementations for use by
pybench.
This module implements various different strategies for measuring
performance timings. It tries to choose the best available method
based on the platforma and available tools.
On Windows, it is recommended to have the Mark Hammond win32
package installed. Alternatively, the Thomas Heller ctypes
packages can also be used.
On Unix systems, the standard resource module provides the highest
resolution timings. Unfortunately, it is not available on all Unix
platforms.
If no supported timing methods based on process time can be found,
the module reverts to the highest resolution wall-clock timer
instead. The system time part will then always be 0.0.
The module exports one public API:
def systimes():
Return the current timer values for measuring user and system
time as tuple of seconds (user_time, system_time).
Copyright (c) 2006, Marc-Andre Lemburg (mal@egenix.com). See the
documentation for further information on copyrights, or contact
the author. All Rights Reserved.
"""
import time, sys, struct
#
# Note: Please keep this module compatible to Python 1.5.2.
#
# TODOs:
#
# * Add ctypes wrapper for new clock_gettime() real-time POSIX APIs;
# these will then provide nano-second resolution where available.
#
# * Add a function that returns the resolution of systimes()
# values, ie. systimesres().
#
### Choose an implementation
SYSTIMES_IMPLEMENTATION = None
USE_CTYPES_GETPROCESSTIMES = 'cytpes GetProcessTimes() wrapper'
USE_WIN32PROCESS_GETPROCESSTIMES = 'win32process.GetProcessTimes()'
USE_RESOURCE_GETRUSAGE = 'resource.getrusage()'
USE_PROCESS_TIME_CLOCK = 'time.clock() (process time)'
USE_WALL_TIME_CLOCK = 'time.clock() (wall-clock)'
USE_WALL_TIME_TIME = 'time.time() (wall-clock)'
if sys.platform[:3] == 'win':
# Windows platform
try:
import win32process
except ImportError:
try:
import ctypes
except ImportError:
# Use the wall-clock implementation time.clock(), since this
# is the highest resolution clock available on Windows
SYSTIMES_IMPLEMENTATION = USE_WALL_TIME_CLOCK
else:
SYSTIMES_IMPLEMENTATION = USE_CTYPES_GETPROCESSTIMES
else:
SYSTIMES_IMPLEMENTATION = USE_WIN32PROCESS_GETPROCESSTIMES
else:
# All other platforms
try:
import resource
except ImportError:
pass
else:
SYSTIMES_IMPLEMENTATION = USE_RESOURCE_GETRUSAGE
# Fall-back solution
if SYSTIMES_IMPLEMENTATION is None:
# Check whether we can use time.clock() as approximation
# for systimes()
start = time.clock()
time.sleep(0.1)
stop = time.clock()
if stop - start < 0.001:
# Looks like time.clock() is usable (and measures process
# time)
SYSTIMES_IMPLEMENTATION = USE_PROCESS_TIME_CLOCK
else:
# Use wall-clock implementation time.time() since this provides
# the highest resolution clock on most systems
SYSTIMES_IMPLEMENTATION = USE_WALL_TIME_TIME
### Implementations
def getrusage_systimes():
return resource.getrusage(resource.RUSAGE_SELF)[:2]
def process_time_clock_systimes():
return (time.clock(), 0.0)
def wall_clock_clock_systimes():
return (time.clock(), 0.0)
def wall_clock_time_systimes():
return (time.time(), 0.0)
# Number of clock ticks per second for the values returned
# by GetProcessTimes() on Windows.
#
# Note: Ticks returned by GetProcessTimes() are 100ns intervals on
# Windows XP. However, the process times are only updated with every
# clock tick and the frequency of these is somewhat lower: depending
# on the OS version between 10ms and 15ms. Even worse, the process
# time seems to be allocated to process currently running when the
# clock interrupt arrives, ie. it is possible that the current time
# slice gets accounted to a different process.
WIN32_PROCESS_TIMES_TICKS_PER_SECOND = 1e7
def win32process_getprocesstimes_systimes():
d = win32process.GetProcessTimes(win32process.GetCurrentProcess())
return (d['UserTime'] / WIN32_PROCESS_TIMES_TICKS_PER_SECOND,
d['KernelTime'] / WIN32_PROCESS_TIMES_TICKS_PER_SECOND)
def ctypes_getprocesstimes_systimes():
creationtime = ctypes.c_ulonglong()
exittime = ctypes.c_ulonglong()
kerneltime = ctypes.c_ulonglong()
usertime = ctypes.c_ulonglong()
rc = ctypes.windll.kernel32.GetProcessTimes(
ctypes.windll.kernel32.GetCurrentProcess(),
ctypes.byref(creationtime),
ctypes.byref(exittime),
ctypes.byref(kerneltime),
ctypes.byref(usertime))
if not rc:
raise TypeError('GetProcessTimes() returned an error')
return (usertime.value / WIN32_PROCESS_TIMES_TICKS_PER_SECOND,
kerneltime.value / WIN32_PROCESS_TIMES_TICKS_PER_SECOND)
# Select the default for the systimes() function
if SYSTIMES_IMPLEMENTATION is USE_RESOURCE_GETRUSAGE:
systimes = getrusage_systimes
elif SYSTIMES_IMPLEMENTATION is USE_PROCESS_TIME_CLOCK:
systimes = process_time_clock_systimes
elif SYSTIMES_IMPLEMENTATION is USE_WALL_TIME_CLOCK:
systimes = wall_clock_clock_systimes
elif SYSTIMES_IMPLEMENTATION is USE_WALL_TIME_TIME:
systimes = wall_clock_time_systimes
elif SYSTIMES_IMPLEMENTATION is USE_WIN32PROCESS_GETPROCESSTIMES:
systimes = win32process_getprocesstimes_systimes
elif SYSTIMES_IMPLEMENTATION is USE_CTYPES_GETPROCESSTIMES:
systimes = ctypes_getprocesstimes_systimes
else:
raise TypeError('no suitable systimes() implementation found')
def processtime():
""" Return the total time spent on the process.
This is the sum of user and system time as returned by
systimes().
"""
user, system = systimes()
return user + system
### Testing
def some_workload():
x = 0
for i in range(10000000):
x = x + 1
def test_workload():
print('Testing systimes() under load conditions')
t0 = systimes()
some_workload()
t1 = systimes()
print('before:', t0)
print('after:', t1)
print('differences:', (t1[0] - t0[0], t1[1] - t0[1]))
print()
def test_idle():
print('Testing systimes() under idle conditions')
t0 = systimes()
time.sleep(1)
t1 = systimes()
print('before:', t0)
print('after:', t1)
print('differences:', (t1[0] - t0[0], t1[1] - t0[1]))
print()
if __name__ == '__main__':
print('Using %s as timer' % SYSTIMES_IMPLEMENTATION)
print()
test_workload()
test_idle()