Skip to content

Commit 6cc2cd1

Browse files
committed
Remove the autorange fallback of timeit/repeat
1 parent 413629b commit 6cc2cd1

File tree

4 files changed

+35
-57
lines changed

4 files changed

+35
-57
lines changed

Doc/library/timeit.rst

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,39 +62,30 @@ Python Interface
6262
The module defines three convenience functions and a public class:
6363

6464

65-
.. function:: timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000, globals=None, target_time=0.2)
65+
.. function:: timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000, globals=None)
6666

6767
Create a :class:`Timer` instance with the given statement, *setup* code and
6868
*timer* function and run its :meth:`.timeit` method with *number* executions.
6969
The optional *globals* argument specifies a namespace in which to execute the
70-
code. If *number* is 0, :meth:`.autorange` method is executed, a convenience
71-
function that calls :meth:`.timeit` repeatedly so that the total time >=
72-
*target_time* second.
70+
code.
7371

7472
.. versionchanged:: 3.5
7573
The optional *globals* parameter was added.
7674

77-
.. versionchanged:: next
78-
The optional *target_time* parameter was added.
7975

80-
81-
.. function:: repeat(stmt='pass', setup='pass', timer=<default timer>, repeat=5, number=1000000, globals=None, target_time=0.2)
76+
.. function:: repeat(stmt='pass', setup='pass', timer=<default timer>, repeat=5, number=1000000, globals=None)
8277

8378
Create a :class:`Timer` instance with the given statement, *setup* code and
8479
*timer* function and run its :meth:`.repeat` method with the given *repeat*
8580
count and *number* executions. The optional *globals* argument specifies a
86-
namespace in which to execute the code. If *number* is 0, the :meth:`autorange`
87-
method is executed, and a convenience function calls :meth:`timeit`
88-
repeatedly so that the total time >= *target_time* seconds.
81+
namespace in which to execute the code.
8982

9083
.. versionchanged:: 3.5
9184
The optional *globals* parameter was added.
9285

9386
.. versionchanged:: 3.7
9487
Default value of *repeat* changed from 3 to 5.
9588

96-
.. versionchanged:: next
97-
The optional *target_time* parameter was added.
9889

9990
.. function:: default_timer()
10091

@@ -105,7 +96,7 @@ The module defines three convenience functions and a public class:
10596
:func:`time.perf_counter` is now the default timer.
10697

10798

108-
.. class:: Timer(stmt='pass', setup='pass', timer=<timer function>, globals=None, target_time=0.2)
99+
.. class:: Timer(stmt='pass', setup='pass', timer=<timer function>, globals=None)
109100

110101
Class for timing execution speed of small code snippets.
111102

@@ -131,9 +122,6 @@ The module defines three convenience functions and a public class:
131122
.. versionchanged:: 3.5
132123
The optional *globals* parameter was added.
133124

134-
.. versionchanged:: next
135-
The optional *target_time* parameter was added.
136-
137125
.. method:: Timer.timeit(number=1000000)
138126

139127
Time *number* executions of the main statement. This executes the setup
@@ -170,6 +158,8 @@ The module defines three convenience functions and a public class:
170158

171159
.. versionadded:: 3.6
172160

161+
.. versionchanged:: next
162+
The optional *target_time* parameter was added.
173163

174164
.. method:: Timer.repeat(repeat=5, number=1000000)
175165

@@ -253,7 +243,8 @@ Where the following options are understood:
253243

254244
.. option:: -t, --target-time=T
255245

256-
calls :meth:`.timeit` repeatedly so that the total time >= *target_time* seconds
246+
if :option:`--number` is 0, the code will run until it takes at
247+
least this many seconds (default: 0.2)
257248

258249
.. versionadded:: next
259250

@@ -272,7 +263,7 @@ similarly.
272263

273264
If :option:`-n` is not given, a suitable number of loops is calculated by trying
274265
increasing numbers from the sequence 1, 2, 5, 10, 20, 50, ... until the total
275-
time is at least 0.2 seconds.
266+
time is at least :option:`--target-time` seconds (default: 0.2).
276267

277268
:func:`default_timer` measurements can be affected by other programs running on
278269
the same machine, so the best thing to do when accurate timing is necessary is

Lib/test/test_timeit.py

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ def timeit(self, stmt, setup, number=None, globals=None):
117117
kwargs['number'] = number
118118
delta_time = t.timeit(**kwargs)
119119
self.assertEqual(self.fake_timer.setup_calls, 1)
120-
self.assertEqual(self.fake_timer.count, number or 1)
121-
self.assertEqual(delta_time, number or (1, 1.0))
120+
self.assertEqual(self.fake_timer.count, number)
121+
self.assertEqual(delta_time, number)
122122

123123
# Takes too long to run in debug build.
124124
#def test_timeit_default_iters(self):
@@ -149,12 +149,7 @@ def test_timeit_callable_stmt_and_setup(self):
149149
def test_timeit_function_zero_iters(self):
150150
delta_time = timeit.timeit(self.fake_stmt, self.fake_setup, number=0,
151151
timer=FakeTimer())
152-
self.assertEqual(delta_time, (1, 1.0))
153-
154-
def test_timeit_function_target_time(self):
155-
delta_time = timeit.timeit(self.fake_stmt, self.fake_setup, number=0,
156-
timer=FakeTimer(), target_time=1)
157-
self.assertEqual(delta_time, (1, 1.0))
152+
self.assertEqual(delta_time, 0)
158153

159154
def test_timeit_globals_args(self):
160155
global _global_timer
@@ -167,9 +162,9 @@ def test_timeit_globals_args(self):
167162
timeit.timeit(stmt='local_timer.inc()', timer=local_timer,
168163
globals=locals(), number=3)
169164

170-
def repeat(self, stmt, setup, repeat=None, number=None, target_time=0.5):
165+
def repeat(self, stmt, setup, repeat=None, number=None):
171166
self.fake_timer = FakeTimer()
172-
t = timeit.Timer(stmt=stmt, setup=setup, timer=self.fake_timer, target_time=target_time)
167+
t = timeit.Timer(stmt=stmt, setup=setup, timer=self.fake_timer)
173168
kwargs = {}
174169
if repeat is None:
175170
repeat = DEFAULT_REPEAT
@@ -181,8 +176,8 @@ def repeat(self, stmt, setup, repeat=None, number=None, target_time=0.5):
181176
kwargs['number'] = number
182177
delta_times = t.repeat(**kwargs)
183178
self.assertEqual(self.fake_timer.setup_calls, repeat)
184-
self.assertEqual(self.fake_timer.count, (repeat * number) if number else repeat)
185-
self.assertEqual(delta_times, repeat * [float(number) or (1, 1.0)])
179+
self.assertEqual(self.fake_timer.count, repeat * number)
180+
self.assertEqual(delta_times, repeat * [float(number)])
186181

187182
# Takes too long to run in debug build.
188183
#def test_repeat_default(self):
@@ -201,10 +196,6 @@ def test_repeat_callable_stmt(self):
201196
self.repeat(self.fake_callable_stmt, self.fake_setup,
202197
repeat=3, number=5)
203198

204-
def test_repeat_callable_target_time(self):
205-
self.repeat(self.fake_callable_stmt, self.fake_setup,
206-
repeat=3, number=5, target_time=1)
207-
208199
def test_repeat_callable_setup(self):
209200
self.repeat(self.fake_stmt, self.fake_callable_setup,
210201
repeat=3, number=5)
@@ -227,7 +218,7 @@ def test_repeat_function_zero_reps(self):
227218
def test_repeat_function_zero_iters(self):
228219
delta_times = timeit.repeat(self.fake_stmt, self.fake_setup, number=0,
229220
timer=FakeTimer())
230-
self.assertEqual(delta_times, DEFAULT_REPEAT * [(1, 1.0)])
221+
self.assertEqual(delta_times, DEFAULT_REPEAT * [0.0])
231222

232223
def assert_exc_string(self, exc_string, expected_exc_name):
233224
exc_lines = exc_string.splitlines()
@@ -373,10 +364,10 @@ def test_main_exception_fixed_reps(self):
373364
s = self.run_main(switches=['-n1', '1/0'])
374365
self.assert_exc_string(error_stringio.getvalue(), 'ZeroDivisionError')
375366

376-
def autorange(self, seconds_per_increment=1/1024, callback=None):
367+
def autorange(self, seconds_per_increment=1/1024, callback=None, target_time=0.2):
377368
timer = FakeTimer(seconds_per_increment=seconds_per_increment)
378369
t = timeit.Timer(stmt=self.fake_stmt, setup=self.fake_setup, timer=timer)
379-
return t.autorange(callback)
370+
return t.autorange(callback, target_time=target_time)
380371

381372
def test_autorange(self):
382373
num_loops, time_taken = self.autorange()
@@ -388,6 +379,11 @@ def test_autorange_second(self):
388379
self.assertEqual(num_loops, 1)
389380
self.assertEqual(time_taken, 1.0)
390381

382+
def test_autorange_with_target_time(self):
383+
num_loops, time_taken = self.autorange(target_time=1.0)
384+
self.assertEqual(num_loops, 2000)
385+
self.assertEqual(time_taken, 2000/1024)
386+
391387
def test_autorange_with_callback(self):
392388
def callback(a, b):
393389
print("{} {:.3f}".format(a, b))

Lib/timeit.py

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,9 @@ class Timer:
103103
"""
104104

105105
def __init__(self, stmt="pass", setup="pass", timer=default_timer,
106-
globals=None, target_time=default_target_time):
106+
globals=None):
107107
"""Constructor. See class doc string."""
108108
self.timer = timer
109-
self.target_time = target_time
110109
local_ns = {}
111110
global_ns = _globals() if globals is None else globals
112111
init = ''
@@ -181,8 +180,6 @@ def timeit(self, number=default_number):
181180
to one million. The main statement, the setup statement and
182181
the timer function to be used are passed to the constructor.
183182
"""
184-
if not number:
185-
return self.autorange()
186183
it = itertools.repeat(None, number)
187184
gcold = gc.isenabled()
188185
gc.disable()
@@ -219,7 +216,7 @@ def repeat(self, repeat=default_repeat, number=default_number):
219216
r.append(t)
220217
return r
221218

222-
def autorange(self, callback=None, target_time=None):
219+
def autorange(self, callback=None, target_time=default_target_time):
223220
"""Return the number of loops and time taken so that
224221
total time >= target_time (default is 0.2 seconds).
225222
@@ -230,8 +227,6 @@ def autorange(self, callback=None, target_time=None):
230227
If *callback* is given and is not None, it will be called after
231228
each trial with two arguments: ``callback(number, time_taken)``.
232229
"""
233-
if target_time is None:
234-
target_time = self.target_time
235230
i = 1
236231
while True:
237232
for j in 1, 2, 5:
@@ -245,17 +240,15 @@ def autorange(self, callback=None, target_time=None):
245240

246241

247242
def timeit(stmt="pass", setup="pass", timer=default_timer,
248-
number=default_number, globals=None,
249-
target_time=default_target_time):
243+
number=default_number, globals=None):
250244
"""Convenience function to create Timer object and call timeit method."""
251-
return Timer(stmt, setup, timer, globals, target_time).timeit(number)
245+
return Timer(stmt, setup, timer, globals).timeit(number)
252246

253247

254248
def repeat(stmt="pass", setup="pass", timer=default_timer,
255-
repeat=default_repeat, number=default_number,
256-
globals=None, target_time=default_target_time):
249+
repeat=default_repeat, number=default_number, globals=None):
257250
"""Convenience function to create Timer object and call repeat method."""
258-
return Timer(stmt, setup, timer, globals, target_time).repeat(repeat, number)
251+
return Timer(stmt, setup, timer, globals).repeat(repeat, number)
259252

260253

261254
def main(args=None, *, _wrap_timer=None):
@@ -338,7 +331,7 @@ def main(args=None, *, _wrap_timer=None):
338331
if _wrap_timer is not None:
339332
timer = _wrap_timer(timer)
340333

341-
t = Timer(stmt, setup, timer, target_time=target_time)
334+
t = Timer(stmt, setup, timer)
342335
if number == 0:
343336
# determine number so that total time >= target_time
344337
callback = None
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
:mod:`timeit`:
2-
- added a new parameter *target_time* to :func:`timeit.timeit` and
3-
:func:`timeit.repeat` methods and :class:`timeit.Timer` class;
4-
- had ``timeit`` and ``repeat`` methods (and functions) fall back
5-
on ``autorange`` if the number is set to 0 or None.
1+
Make the target time of :meth:`timeit.Timer.autorange` configurable
2+
and add ``--target-time`` option to the command-line interface of
3+
:mod:`timeit`:.

0 commit comments

Comments
 (0)