timeit.Timer('for i in range(10): oct(i)', 'gc.enable()').timeit()
- .. method:: Timer.autorange(callback=None)
+ .. method:: Timer.autorange(callback=None, target_time=None)
Automatically determine how many times to call :meth:`.timeit`.
This is a convenience function that calls :meth:`.timeit` repeatedly
- so that the total time >= 0.2 second, returning the eventual
+ so that the total time >= *Timer.target_time* seconds, returning the eventual
(number of loops, time taken for that number of loops). It calls
:meth:`.timeit` with increasing numbers from the sequence 1, 2, 5,
- 10, 20, 50, ... until the time taken is at least 0.2 seconds.
+ 10, 20, 50, ... until the time taken is at least *target_time* seconds.
If *callback* is given and is not ``None``, it will be called after
each trial with two arguments: ``callback(number, time_taken)``.
.. versionadded:: 3.6
+ .. versionchanged:: next
+ The optional *target_time* parameter was added.
+
.. method:: Timer.repeat(repeat=5, number=1000000)
.. versionadded:: 3.5
+.. option:: -t, --target-time=T
+
+ if :option:`--number` is 0, the code will run until it takes at
+ least this many seconds (default: 0.2)
+
+ .. versionadded:: next
+
.. option:: -v, --verbose
print raw timing results; repeat for more digits precision
If :option:`-n` is not given, a suitable number of loops is calculated by trying
increasing numbers from the sequence 1, 2, 5, 10, 20, 50, ... until the total
-time is at least 0.2 seconds.
+time is at least :option:`--target-time` seconds (default: 0.2).
:func:`default_timer` measurements can be affected by other programs running on
the same machine, so the best thing to do when accurate timing is necessary is
s = self.run_main(switches=['-n1', '1/0'])
self.assert_exc_string(error_stringio.getvalue(), 'ZeroDivisionError')
- def autorange(self, seconds_per_increment=1/1024, callback=None):
+ def autorange(self, seconds_per_increment=1/1024, callback=None, target_time=0.2):
timer = FakeTimer(seconds_per_increment=seconds_per_increment)
t = timeit.Timer(stmt=self.fake_stmt, setup=self.fake_setup, timer=timer)
- return t.autorange(callback)
+ return t.autorange(callback, target_time=target_time)
def test_autorange(self):
num_loops, time_taken = self.autorange()
self.assertEqual(num_loops, 1)
self.assertEqual(time_taken, 1.0)
+ def test_autorange_with_target_time(self):
+ num_loops, time_taken = self.autorange(target_time=1.0)
+ self.assertEqual(num_loops, 2000)
+ self.assertEqual(time_taken, 2000/1024)
+
def test_autorange_with_callback(self):
def callback(a, b):
print("{} {:.3f}".format(a, b))
Library usage: see the Timer class.
Command line usage:
- python timeit.py [-n N] [-r N] [-s S] [-p] [-h] [--] [statement]
+ python timeit.py [-n N] [-r N] [-s S] [-p] [-h] [-t T] [--] [statement]
Options:
-n/--number N: how many times to execute 'statement' (default: see below)
-p/--process: use time.process_time() (default is time.perf_counter())
-v/--verbose: print raw timing results; repeat for more digits precision
-u/--unit: set the output time unit (nsec, usec, msec, or sec)
+ -t/--target-time T: if --number is 0 the code will run until it
+ takes *at least* this many seconds
+ (default: 0.2)
-h/--help: print this usage message and exit
--: separate options from statement, use when statement starts with -
statement: statement to be timed (default 'pass')
If -n is not given, a suitable number of loops is calculated by trying
increasing numbers from the sequence 1, 2, 5, 10, 20, 50, ... until the
-total time is at least 0.2 seconds.
+total time is at least --target-time seconds.
Note: there is a certain baseline overhead associated with executing a
pass statement. It differs between versions. The code here doesn't try
default_number = 1000000
default_repeat = 5
default_timer = time.perf_counter
+default_target_time = 0.2
_globals = globals
r.append(t)
return r
- def autorange(self, callback=None):
- """Return the number of loops and time taken so that total time >= 0.2.
+ def autorange(self, callback=None, target_time=default_target_time):
+ """Return the number of loops and time taken so that
+ total time >= target_time (default is 0.2 seconds).
Calls the timeit method with increasing numbers from the sequence
- 1, 2, 5, 10, 20, 50, ... until the time taken is at least 0.2
- second. Returns (number, time_taken).
+ 1, 2, 5, 10, 20, 50, ... until the target time is reached.
+ Returns (number, time_taken).
If *callback* is given and is not None, it will be called after
each trial with two arguments: ``callback(number, time_taken)``.
time_taken = self.timeit(number)
if callback:
callback(number, time_taken)
- if time_taken >= 0.2:
+ if time_taken >= target_time:
return (number, time_taken)
i *= 10
colorize = _colorize.can_colorize()
try:
- opts, args = getopt.getopt(args, "n:u:s:r:pvh",
+ opts, args = getopt.getopt(args, "n:u:s:r:pt:vh",
["number=", "setup=", "repeat=",
- "process", "verbose", "unit=", "help"])
+ "process", "target-time=",
+ "verbose", "unit=", "help"])
except getopt.error as err:
print(err)
print("use -h/--help for command line help")
timer = default_timer
stmt = "\n".join(args) or "pass"
number = 0 # auto-determine
+ target_time = default_target_time
setup = []
repeat = default_repeat
verbose = 0
repeat = 1
if o in ("-p", "--process"):
timer = time.process_time
+ if o in ("-t", "--target-time"):
+ target_time = float(a)
if o in ("-v", "--verbose"):
if verbose:
precision += 1
t = Timer(stmt, setup, timer)
if number == 0:
- # determine number so that 0.2 <= total time < 2.0
+ # determine number so that total time >= target_time
callback = None
if verbose:
def callback(number, time_taken):
print(msg.format(num=number, s='s' if plural else '',
secs=time_taken, prec=precision))
try:
- number, _ = t.autorange(callback)
+ number, _ = t.autorange(callback, target_time)
except:
t.print_exc(colorize=colorize)
return 1