summaryrefslogtreecommitdiff
path: root/AppPkg/Applications/Python/Python-2.7.2/Tools/pybench/pybench.py
diff options
context:
space:
mode:
Diffstat (limited to 'AppPkg/Applications/Python/Python-2.7.2/Tools/pybench/pybench.py')
-rw-r--r--AppPkg/Applications/Python/Python-2.7.2/Tools/pybench/pybench.py961
1 files changed, 961 insertions, 0 deletions
diff --git a/AppPkg/Applications/Python/Python-2.7.2/Tools/pybench/pybench.py b/AppPkg/Applications/Python/Python-2.7.2/Tools/pybench/pybench.py
new file mode 100644
index 0000000000..4bfc7f28df
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.2/Tools/pybench/pybench.py
@@ -0,0 +1,961 @@
+#!/usr/local/bin/python -O
+
+""" A Python Benchmark Suite
+
+"""
+#
+# Note: Please keep this module compatible to Python 1.5.2.
+#
+# Tests may include features in later Python versions, but these
+# should then be embedded in try-except clauses in the configuration
+# module Setup.py.
+#
+
+# pybench Copyright
+__copyright__ = """\
+Copyright (c), 1997-2006, Marc-Andre Lemburg (mal@lemburg.com)
+Copyright (c), 2000-2006, eGenix.com Software GmbH (info@egenix.com)
+
+ All Rights Reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee or royalty is hereby
+granted, provided that the above copyright notice appear in all copies
+and that both that copyright notice and this permission notice appear
+in supporting documentation or portions thereof, including
+modifications, that you make.
+
+THE AUTHOR MARC-ANDRE LEMBURG DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !
+"""
+
+import sys, time, operator, string, platform
+from CommandLine import *
+
+try:
+ import cPickle
+ pickle = cPickle
+except ImportError:
+ import pickle
+
+# Version number; version history: see README file !
+__version__ = '2.0'
+
+### Constants
+
+# Second fractions
+MILLI_SECONDS = 1e3
+MICRO_SECONDS = 1e6
+
+# Percent unit
+PERCENT = 100
+
+# Horizontal line length
+LINE = 79
+
+# Minimum test run-time
+MIN_TEST_RUNTIME = 1e-3
+
+# Number of calibration runs to use for calibrating the tests
+CALIBRATION_RUNS = 20
+
+# Number of calibration loops to run for each calibration run
+CALIBRATION_LOOPS = 20
+
+# Allow skipping calibration ?
+ALLOW_SKIPPING_CALIBRATION = 1
+
+# Timer types
+TIMER_TIME_TIME = 'time.time'
+TIMER_TIME_CLOCK = 'time.clock'
+TIMER_SYSTIMES_PROCESSTIME = 'systimes.processtime'
+
+# Choose platform default timer
+if sys.platform[:3] == 'win':
+ # On WinXP this has 2.5ms resolution
+ TIMER_PLATFORM_DEFAULT = TIMER_TIME_CLOCK
+else:
+ # On Linux this has 1ms resolution
+ TIMER_PLATFORM_DEFAULT = TIMER_TIME_TIME
+
+# Print debug information ?
+_debug = 0
+
+### Helpers
+
+def get_timer(timertype):
+
+ if timertype == TIMER_TIME_TIME:
+ return time.time
+ elif timertype == TIMER_TIME_CLOCK:
+ return time.clock
+ elif timertype == TIMER_SYSTIMES_PROCESSTIME:
+ import systimes
+ return systimes.processtime
+ else:
+ raise TypeError('unknown timer type: %s' % timertype)
+
+def get_machine_details():
+
+ if _debug:
+ print 'Getting machine details...'
+ buildno, builddate = platform.python_build()
+ python = platform.python_version()
+ try:
+ unichr(100000)
+ except ValueError:
+ # UCS2 build (standard)
+ unicode = 'UCS2'
+ except NameError:
+ unicode = None
+ else:
+ # UCS4 build (most recent Linux distros)
+ unicode = 'UCS4'
+ bits, linkage = platform.architecture()
+ return {
+ 'platform': platform.platform(),
+ 'processor': platform.processor(),
+ 'executable': sys.executable,
+ 'implementation': getattr(platform, 'python_implementation',
+ lambda:'n/a')(),
+ 'python': platform.python_version(),
+ 'compiler': platform.python_compiler(),
+ 'buildno': buildno,
+ 'builddate': builddate,
+ 'unicode': unicode,
+ 'bits': bits,
+ }
+
+def print_machine_details(d, indent=''):
+
+ l = ['Machine Details:',
+ ' Platform ID: %s' % d.get('platform', 'n/a'),
+ ' Processor: %s' % d.get('processor', 'n/a'),
+ '',
+ 'Python:',
+ ' Implementation: %s' % d.get('implementation', 'n/a'),
+ ' Executable: %s' % d.get('executable', 'n/a'),
+ ' Version: %s' % d.get('python', 'n/a'),
+ ' Compiler: %s' % d.get('compiler', 'n/a'),
+ ' Bits: %s' % d.get('bits', 'n/a'),
+ ' Build: %s (#%s)' % (d.get('builddate', 'n/a'),
+ d.get('buildno', 'n/a')),
+ ' Unicode: %s' % d.get('unicode', 'n/a'),
+ ]
+ print indent + string.join(l, '\n' + indent) + '\n'
+
+### Test baseclass
+
+class Test:
+
+ """ All test must have this class as baseclass. It provides
+ the necessary interface to the benchmark machinery.
+
+ The tests must set .rounds to a value high enough to let the
+ test run between 20-50 seconds. This is needed because
+ clock()-timing only gives rather inaccurate values (on Linux,
+ for example, it is accurate to a few hundreths of a
+ second). If you don't want to wait that long, use a warp
+ factor larger than 1.
+
+ It is also important to set the .operations variable to a
+ value representing the number of "virtual operations" done per
+ call of .run().
+
+ If you change a test in some way, don't forget to increase
+ its version number.
+
+ """
+
+ ### Instance variables that each test should override
+
+ # Version number of the test as float (x.yy); this is important
+ # for comparisons of benchmark runs - tests with unequal version
+ # number will not get compared.
+ version = 2.0
+
+ # The number of abstract operations done in each round of the
+ # test. An operation is the basic unit of what you want to
+ # measure. The benchmark will output the amount of run-time per
+ # operation. Note that in order to raise the measured timings
+ # significantly above noise level, it is often required to repeat
+ # sets of operations more than once per test round. The measured
+ # overhead per test round should be less than 1 second.
+ operations = 1
+
+ # Number of rounds to execute per test run. This should be
+ # adjusted to a figure that results in a test run-time of between
+ # 1-2 seconds.
+ rounds = 100000
+
+ ### Internal variables
+
+ # Mark this class as implementing a test
+ is_a_test = 1
+
+ # Last timing: (real, run, overhead)
+ last_timing = (0.0, 0.0, 0.0)
+
+ # Warp factor to use for this test
+ warp = 1
+
+ # Number of calibration runs to use
+ calibration_runs = CALIBRATION_RUNS
+
+ # List of calibration timings
+ overhead_times = None
+
+ # List of test run timings
+ times = []
+
+ # Timer used for the benchmark
+ timer = TIMER_PLATFORM_DEFAULT
+
+ def __init__(self, warp=None, calibration_runs=None, timer=None):
+
+ # Set parameters
+ if warp is not None:
+ self.rounds = int(self.rounds / warp)
+ if self.rounds == 0:
+ raise ValueError('warp factor set too high')
+ self.warp = warp
+ if calibration_runs is not None:
+ if (not ALLOW_SKIPPING_CALIBRATION and
+ calibration_runs < 1):
+ raise ValueError('at least one calibration run is required')
+ self.calibration_runs = calibration_runs
+ if timer is not None:
+ self.timer = timer
+
+ # Init variables
+ self.times = []
+ self.overhead_times = []
+
+ # We want these to be in the instance dict, so that pickle
+ # saves them
+ self.version = self.version
+ self.operations = self.operations
+ self.rounds = self.rounds
+
+ def get_timer(self):
+
+ """ Return the timer function to use for the test.
+
+ """
+ return get_timer(self.timer)
+
+ def compatible(self, other):
+
+ """ Return 1/0 depending on whether the test is compatible
+ with the other Test instance or not.
+
+ """
+ if self.version != other.version:
+ return 0
+ if self.rounds != other.rounds:
+ return 0
+ return 1
+
+ def calibrate_test(self):
+
+ if self.calibration_runs == 0:
+ self.overhead_times = [0.0]
+ return
+
+ calibrate = self.calibrate
+ timer = self.get_timer()
+ calibration_loops = range(CALIBRATION_LOOPS)
+
+ # Time the calibration loop overhead
+ prep_times = []
+ for i in range(self.calibration_runs):
+ t = timer()
+ for i in calibration_loops:
+ pass
+ t = timer() - t
+ prep_times.append(t / CALIBRATION_LOOPS)
+ min_prep_time = min(prep_times)
+ if _debug:
+ print
+ print 'Calib. prep time = %.6fms' % (
+ min_prep_time * MILLI_SECONDS)
+
+ # Time the calibration runs (doing CALIBRATION_LOOPS loops of
+ # .calibrate() method calls each)
+ for i in range(self.calibration_runs):
+ t = timer()
+ for i in calibration_loops:
+ calibrate()
+ t = timer() - t
+ self.overhead_times.append(t / CALIBRATION_LOOPS
+ - min_prep_time)
+
+ # Check the measured times
+ min_overhead = min(self.overhead_times)
+ max_overhead = max(self.overhead_times)
+ if _debug:
+ print 'Calib. overhead time = %.6fms' % (
+ min_overhead * MILLI_SECONDS)
+ if min_overhead < 0.0:
+ raise ValueError('calibration setup did not work')
+ if max_overhead - min_overhead > 0.1:
+ raise ValueError(
+ 'overhead calibration timing range too inaccurate: '
+ '%r - %r' % (min_overhead, max_overhead))
+
+ def run(self):
+
+ """ Run the test in two phases: first calibrate, then
+ do the actual test. Be careful to keep the calibration
+ timing low w/r to the test timing.
+
+ """
+ test = self.test
+ timer = self.get_timer()
+
+ # Get calibration
+ min_overhead = min(self.overhead_times)
+
+ # Test run
+ t = timer()
+ test()
+ t = timer() - t
+ if t < MIN_TEST_RUNTIME:
+ raise ValueError('warp factor too high: '
+ 'test times are < 10ms')
+ eff_time = t - min_overhead
+ if eff_time < 0:
+ raise ValueError('wrong calibration')
+ self.last_timing = (eff_time, t, min_overhead)
+ self.times.append(eff_time)
+
+ def calibrate(self):
+
+ """ Calibrate the test.
+
+ This method should execute everything that is needed to
+ setup and run the test - except for the actual operations
+ that you intend to measure. pybench uses this method to
+ measure the test implementation overhead.
+
+ """
+ return
+
+ def test(self):
+
+ """ Run the test.
+
+ The test needs to run self.rounds executing
+ self.operations number of operations each.
+
+ """
+ return
+
+ def stat(self):
+
+ """ Return test run statistics as tuple:
+
+ (minimum run time,
+ average run time,
+ total run time,
+ average time per operation,
+ minimum overhead time)
+
+ """
+ runs = len(self.times)
+ if runs == 0:
+ return 0.0, 0.0, 0.0, 0.0
+ min_time = min(self.times)
+ total_time = reduce(operator.add, self.times, 0.0)
+ avg_time = total_time / float(runs)
+ operation_avg = total_time / float(runs
+ * self.rounds
+ * self.operations)
+ if self.overhead_times:
+ min_overhead = min(self.overhead_times)
+ else:
+ min_overhead = self.last_timing[2]
+ return min_time, avg_time, total_time, operation_avg, min_overhead
+
+### Load Setup
+
+# This has to be done after the definition of the Test class, since
+# the Setup module will import subclasses using this class.
+
+import Setup
+
+### Benchmark base class
+
+class Benchmark:
+
+ # Name of the benchmark
+ name = ''
+
+ # Number of benchmark rounds to run
+ rounds = 1
+
+ # Warp factor use to run the tests
+ warp = 1 # Warp factor
+
+ # Average benchmark round time
+ roundtime = 0
+
+ # Benchmark version number as float x.yy
+ version = 2.0
+
+ # Produce verbose output ?
+ verbose = 0
+
+ # Dictionary with the machine details
+ machine_details = None
+
+ # Timer used for the benchmark
+ timer = TIMER_PLATFORM_DEFAULT
+
+ def __init__(self, name, verbose=None, timer=None, warp=None,
+ calibration_runs=None):
+
+ if name:
+ self.name = name
+ else:
+ self.name = '%04i-%02i-%02i %02i:%02i:%02i' % \
+ (time.localtime(time.time())[:6])
+ if verbose is not None:
+ self.verbose = verbose
+ if timer is not None:
+ self.timer = timer
+ if warp is not None:
+ self.warp = warp
+ if calibration_runs is not None:
+ self.calibration_runs = calibration_runs
+
+ # Init vars
+ self.tests = {}
+ if _debug:
+ print 'Getting machine details...'
+ self.machine_details = get_machine_details()
+
+ # Make .version an instance attribute to have it saved in the
+ # Benchmark pickle
+ self.version = self.version
+
+ def get_timer(self):
+
+ """ Return the timer function to use for the test.
+
+ """
+ return get_timer(self.timer)
+
+ def compatible(self, other):
+
+ """ Return 1/0 depending on whether the benchmark is
+ compatible with the other Benchmark instance or not.
+
+ """
+ if self.version != other.version:
+ return 0
+ if (self.machine_details == other.machine_details and
+ self.timer != other.timer):
+ return 0
+ if (self.calibration_runs == 0 and
+ other.calibration_runs != 0):
+ return 0
+ if (self.calibration_runs != 0 and
+ other.calibration_runs == 0):
+ return 0
+ return 1
+
+ def load_tests(self, setupmod, limitnames=None):
+
+ # Add tests
+ if self.verbose:
+ print 'Searching for tests ...'
+ print '--------------------------------------'
+ for testclass in setupmod.__dict__.values():
+ if not hasattr(testclass, 'is_a_test'):
+ continue
+ name = testclass.__name__
+ if name == 'Test':
+ continue
+ if (limitnames is not None and
+ limitnames.search(name) is None):
+ continue
+ self.tests[name] = testclass(
+ warp=self.warp,
+ calibration_runs=self.calibration_runs,
+ timer=self.timer)
+ l = self.tests.keys()
+ l.sort()
+ if self.verbose:
+ for name in l:
+ print ' %s' % name
+ print '--------------------------------------'
+ print ' %i tests found' % len(l)
+ print
+
+ def calibrate(self):
+
+ print 'Calibrating tests. Please wait...',
+ sys.stdout.flush()
+ if self.verbose:
+ print
+ print
+ print 'Test min max'
+ print '-' * LINE
+ tests = self.tests.items()
+ tests.sort()
+ for i in range(len(tests)):
+ name, test = tests[i]
+ test.calibrate_test()
+ if self.verbose:
+ print '%30s: %6.3fms %6.3fms' % \
+ (name,
+ min(test.overhead_times) * MILLI_SECONDS,
+ max(test.overhead_times) * MILLI_SECONDS)
+ if self.verbose:
+ print
+ print 'Done with the calibration.'
+ else:
+ print 'done.'
+ print
+
+ def run(self):
+
+ tests = self.tests.items()
+ tests.sort()
+ timer = self.get_timer()
+ print 'Running %i round(s) of the suite at warp factor %i:' % \
+ (self.rounds, self.warp)
+ print
+ self.roundtimes = []
+ for i in range(self.rounds):
+ if self.verbose:
+ print ' Round %-25i effective absolute overhead' % (i+1)
+ total_eff_time = 0.0
+ for j in range(len(tests)):
+ name, test = tests[j]
+ if self.verbose:
+ print '%30s:' % name,
+ test.run()
+ (eff_time, abs_time, min_overhead) = test.last_timing
+ total_eff_time = total_eff_time + eff_time
+ if self.verbose:
+ print ' %5.0fms %5.0fms %7.3fms' % \
+ (eff_time * MILLI_SECONDS,
+ abs_time * MILLI_SECONDS,
+ min_overhead * MILLI_SECONDS)
+ self.roundtimes.append(total_eff_time)
+ if self.verbose:
+ print (' '
+ ' ------------------------------')
+ print (' '
+ ' Totals: %6.0fms' %
+ (total_eff_time * MILLI_SECONDS))
+ print
+ else:
+ print '* Round %i done in %.3f seconds.' % (i+1,
+ total_eff_time)
+ print
+
+ def stat(self):
+
+ """ Return benchmark run statistics as tuple:
+
+ (minimum round time,
+ average round time,
+ maximum round time)
+
+ XXX Currently not used, since the benchmark does test
+ statistics across all rounds.
+
+ """
+ runs = len(self.roundtimes)
+ if runs == 0:
+ return 0.0, 0.0
+ min_time = min(self.roundtimes)
+ total_time = reduce(operator.add, self.roundtimes, 0.0)
+ avg_time = total_time / float(runs)
+ max_time = max(self.roundtimes)
+ return (min_time, avg_time, max_time)
+
+ def print_header(self, title='Benchmark'):
+
+ print '-' * LINE
+ print '%s: %s' % (title, self.name)
+ print '-' * LINE
+ print
+ print ' Rounds: %s' % self.rounds
+ print ' Warp: %s' % self.warp
+ print ' Timer: %s' % self.timer
+ print
+ if self.machine_details:
+ print_machine_details(self.machine_details, indent=' ')
+ print
+
+ def print_benchmark(self, hidenoise=0, limitnames=None):
+
+ print ('Test '
+ ' minimum average operation overhead')
+ print '-' * LINE
+ tests = self.tests.items()
+ tests.sort()
+ total_min_time = 0.0
+ total_avg_time = 0.0
+ for name, test in tests:
+ if (limitnames is not None and
+ limitnames.search(name) is None):
+ continue
+ (min_time,
+ avg_time,
+ total_time,
+ op_avg,
+ min_overhead) = test.stat()
+ total_min_time = total_min_time + min_time
+ total_avg_time = total_avg_time + avg_time
+ print '%30s: %5.0fms %5.0fms %6.2fus %7.3fms' % \
+ (name,
+ min_time * MILLI_SECONDS,
+ avg_time * MILLI_SECONDS,
+ op_avg * MICRO_SECONDS,
+ min_overhead *MILLI_SECONDS)
+ print '-' * LINE
+ print ('Totals: '
+ ' %6.0fms %6.0fms' %
+ (total_min_time * MILLI_SECONDS,
+ total_avg_time * MILLI_SECONDS,
+ ))
+ print
+
+ def print_comparison(self, compare_to, hidenoise=0, limitnames=None):
+
+ # Check benchmark versions
+ if compare_to.version != self.version:
+ print ('* Benchmark versions differ: '
+ 'cannot compare this benchmark to "%s" !' %
+ compare_to.name)
+ print
+ self.print_benchmark(hidenoise=hidenoise,
+ limitnames=limitnames)
+ return
+
+ # Print header
+ compare_to.print_header('Comparing with')
+ print ('Test '
+ ' minimum run-time average run-time')
+ print (' '
+ ' this other diff this other diff')
+ print '-' * LINE
+
+ # Print test comparisons
+ tests = self.tests.items()
+ tests.sort()
+ total_min_time = other_total_min_time = 0.0
+ total_avg_time = other_total_avg_time = 0.0
+ benchmarks_compatible = self.compatible(compare_to)
+ tests_compatible = 1
+ for name, test in tests:
+ if (limitnames is not None and
+ limitnames.search(name) is None):
+ continue
+ (min_time,
+ avg_time,
+ total_time,
+ op_avg,
+ min_overhead) = test.stat()
+ total_min_time = total_min_time + min_time
+ total_avg_time = total_avg_time + avg_time
+ try:
+ other = compare_to.tests[name]
+ except KeyError:
+ other = None
+ if other is None:
+ # Other benchmark doesn't include the given test
+ min_diff, avg_diff = 'n/a', 'n/a'
+ other_min_time = 0.0
+ other_avg_time = 0.0
+ tests_compatible = 0
+ else:
+ (other_min_time,
+ other_avg_time,
+ other_total_time,
+ other_op_avg,
+ other_min_overhead) = other.stat()
+ other_total_min_time = other_total_min_time + other_min_time
+ other_total_avg_time = other_total_avg_time + other_avg_time
+ if (benchmarks_compatible and
+ test.compatible(other)):
+ # Both benchmark and tests are comparable
+ min_diff = ((min_time * self.warp) /
+ (other_min_time * other.warp) - 1.0)
+ avg_diff = ((avg_time * self.warp) /
+ (other_avg_time * other.warp) - 1.0)
+ if hidenoise and abs(min_diff) < 10.0:
+ min_diff = ''
+ else:
+ min_diff = '%+5.1f%%' % (min_diff * PERCENT)
+ if hidenoise and abs(avg_diff) < 10.0:
+ avg_diff = ''
+ else:
+ avg_diff = '%+5.1f%%' % (avg_diff * PERCENT)
+ else:
+ # Benchmark or tests are not comparable
+ min_diff, avg_diff = 'n/a', 'n/a'
+ tests_compatible = 0
+ print '%30s: %5.0fms %5.0fms %7s %5.0fms %5.0fms %7s' % \
+ (name,
+ min_time * MILLI_SECONDS,
+ other_min_time * MILLI_SECONDS * compare_to.warp / self.warp,
+ min_diff,
+ avg_time * MILLI_SECONDS,
+ other_avg_time * MILLI_SECONDS * compare_to.warp / self.warp,
+ avg_diff)
+ print '-' * LINE
+
+ # Summarise test results
+ if not benchmarks_compatible or not tests_compatible:
+ min_diff, avg_diff = 'n/a', 'n/a'
+ else:
+ if other_total_min_time != 0.0:
+ min_diff = '%+5.1f%%' % (
+ ((total_min_time * self.warp) /
+ (other_total_min_time * compare_to.warp) - 1.0) * PERCENT)
+ else:
+ min_diff = 'n/a'
+ if other_total_avg_time != 0.0:
+ avg_diff = '%+5.1f%%' % (
+ ((total_avg_time * self.warp) /
+ (other_total_avg_time * compare_to.warp) - 1.0) * PERCENT)
+ else:
+ avg_diff = 'n/a'
+ print ('Totals: '
+ ' %5.0fms %5.0fms %7s %5.0fms %5.0fms %7s' %
+ (total_min_time * MILLI_SECONDS,
+ (other_total_min_time * compare_to.warp/self.warp
+ * MILLI_SECONDS),
+ min_diff,
+ total_avg_time * MILLI_SECONDS,
+ (other_total_avg_time * compare_to.warp/self.warp
+ * MILLI_SECONDS),
+ avg_diff
+ ))
+ print
+ print '(this=%s, other=%s)' % (self.name,
+ compare_to.name)
+ print
+
+class PyBenchCmdline(Application):
+
+ header = ("PYBENCH - a benchmark test suite for Python "
+ "interpreters/compilers.")
+
+ version = __version__
+
+ debug = _debug
+
+ options = [ArgumentOption('-n',
+ 'number of rounds',
+ Setup.Number_of_rounds),
+ ArgumentOption('-f',
+ 'save benchmark to file arg',
+ ''),
+ ArgumentOption('-c',
+ 'compare benchmark with the one in file arg',
+ ''),
+ ArgumentOption('-s',
+ 'show benchmark in file arg, then exit',
+ ''),
+ ArgumentOption('-w',
+ 'set warp factor to arg',
+ Setup.Warp_factor),
+ ArgumentOption('-t',
+ 'run only tests with names matching arg',
+ ''),
+ ArgumentOption('-C',
+ 'set the number of calibration runs to arg',
+ CALIBRATION_RUNS),
+ SwitchOption('-d',
+ 'hide noise in comparisons',
+ 0),
+ SwitchOption('-v',
+ 'verbose output (not recommended)',
+ 0),
+ SwitchOption('--with-gc',
+ 'enable garbage collection',
+ 0),
+ SwitchOption('--with-syscheck',
+ 'use default sys check interval',
+ 0),
+ ArgumentOption('--timer',
+ 'use given timer',
+ TIMER_PLATFORM_DEFAULT),
+ ]
+
+ about = """\
+The normal operation is to run the suite and display the
+results. Use -f to save them for later reuse or comparisons.
+
+Available timers:
+
+ time.time
+ time.clock
+ systimes.processtime
+
+Examples:
+
+python2.1 pybench.py -f p21.pybench
+python2.5 pybench.py -f p25.pybench
+python pybench.py -s p25.pybench -c p21.pybench
+"""
+ copyright = __copyright__
+
+ def main(self):
+
+ rounds = self.values['-n']
+ reportfile = self.values['-f']
+ show_bench = self.values['-s']
+ compare_to = self.values['-c']
+ hidenoise = self.values['-d']
+ warp = int(self.values['-w'])
+ withgc = self.values['--with-gc']
+ limitnames = self.values['-t']
+ if limitnames:
+ if _debug:
+ print '* limiting test names to one with substring "%s"' % \
+ limitnames
+ limitnames = re.compile(limitnames, re.I)
+ else:
+ limitnames = None
+ verbose = self.verbose
+ withsyscheck = self.values['--with-syscheck']
+ calibration_runs = self.values['-C']
+ timer = self.values['--timer']
+
+ print '-' * LINE
+ print 'PYBENCH %s' % __version__
+ print '-' * LINE
+ print '* using %s %s' % (
+ getattr(platform, 'python_implementation', lambda:'Python')(),
+ string.join(string.split(sys.version), ' '))
+
+ # Switch off garbage collection
+ if not withgc:
+ try:
+ import gc
+ except ImportError:
+ print '* Python version doesn\'t support garbage collection'
+ else:
+ try:
+ gc.disable()
+ except NotImplementedError:
+ print '* Python version doesn\'t support gc.disable'
+ else:
+ print '* disabled garbage collection'
+
+ # "Disable" sys check interval
+ if not withsyscheck:
+ # Too bad the check interval uses an int instead of a long...
+ value = 2147483647
+ try:
+ sys.setcheckinterval(value)
+ except (AttributeError, NotImplementedError):
+ print '* Python version doesn\'t support sys.setcheckinterval'
+ else:
+ print '* system check interval set to maximum: %s' % value
+
+ if timer == TIMER_SYSTIMES_PROCESSTIME:
+ import systimes
+ print '* using timer: systimes.processtime (%s)' % \
+ systimes.SYSTIMES_IMPLEMENTATION
+ else:
+ print '* using timer: %s' % timer
+
+ print
+
+ if compare_to:
+ try:
+ f = open(compare_to,'rb')
+ bench = pickle.load(f)
+ bench.name = compare_to
+ f.close()
+ compare_to = bench
+ except IOError, reason:
+ print '* Error opening/reading file %s: %s' % (
+ repr(compare_to),
+ reason)
+ compare_to = None
+
+ if show_bench:
+ try:
+ f = open(show_bench,'rb')
+ bench = pickle.load(f)
+ bench.name = show_bench
+ f.close()
+ bench.print_header()
+ if compare_to:
+ bench.print_comparison(compare_to,
+ hidenoise=hidenoise,
+ limitnames=limitnames)
+ else:
+ bench.print_benchmark(hidenoise=hidenoise,
+ limitnames=limitnames)
+ except IOError, reason:
+ print '* Error opening/reading file %s: %s' % (
+ repr(show_bench),
+ reason)
+ print
+ return
+
+ if reportfile:
+ print 'Creating benchmark: %s (rounds=%i, warp=%i)' % \
+ (reportfile, rounds, warp)
+ print
+
+ # Create benchmark object
+ bench = Benchmark(reportfile,
+ verbose=verbose,
+ timer=timer,
+ warp=warp,
+ calibration_runs=calibration_runs)
+ bench.rounds = rounds
+ bench.load_tests(Setup, limitnames=limitnames)
+ try:
+ bench.calibrate()
+ bench.run()
+ except KeyboardInterrupt:
+ print
+ print '*** KeyboardInterrupt -- Aborting'
+ print
+ return
+ bench.print_header()
+ if compare_to:
+ bench.print_comparison(compare_to,
+ hidenoise=hidenoise,
+ limitnames=limitnames)
+ else:
+ bench.print_benchmark(hidenoise=hidenoise,
+ limitnames=limitnames)
+
+ # Ring bell
+ sys.stderr.write('\007')
+
+ if reportfile:
+ try:
+ f = open(reportfile,'wb')
+ bench.name = reportfile
+ pickle.dump(bench,f)
+ f.close()
+ except IOError, reason:
+ print '* Error opening/writing reportfile'
+ except IOError, reason:
+ print '* Error opening/writing reportfile %s: %s' % (
+ reportfile,
+ reason)
+ print
+
+if __name__ == '__main__':
+ PyBenchCmdline()