cpython: 3aba5552b976 (original) (raw)
--- a/Lib/test/test_timeit.py +++ b/Lib/test/test_timeit.py @@ -226,7 +226,7 @@ class TestTimeit(unittest.TestCase): t.print_exc(s) self.assert_exc_string(s.getvalue(), 'ZeroDivisionError')
def run_main(self, seconds_per_increment=1.0, switches=None, timer=None): if timer is None: @@ -252,7 +252,7 @@ class TestTimeit(unittest.TestCase): def test_main_seconds(self): s = self.run_main(seconds_per_increment=5.5)
self.assertEqual(s, "10 loops, best of 3: 5.5 sec per loop\n")[](#l1.16)
self.assertEqual(s, "1 loop, best of 3: 5.5 sec per loop\n")[](#l1.17)
def test_main_milliseconds(self): s = self.run_main(seconds_per_increment=0.0055) @@ -280,11 +280,11 @@ class TestTimeit(unittest.TestCase): def test_main_fixed_reps(self): s = self.run_main(seconds_per_increment=60.0, switches=['-r9'])
self.assertEqual(s, "10 loops, best of 9: 60 sec per loop\n")[](#l1.25)
self.assertEqual(s, "1 loop, best of 9: 60 sec per loop\n")[](#l1.26)
def test_main_negative_reps(self): s = self.run_main(seconds_per_increment=60.0, switches=['-r-5'])
self.assertEqual(s, "10 loops, best of 1: 60 sec per loop\n")[](#l1.30)
self.assertEqual(s, "1 loop, best of 1: 60 sec per loop\n")[](#l1.31)
@unittest.skipIf(sys.flags.optimize >= 2, "need doc") def test_main_help(self): @@ -308,14 +308,15 @@ class TestTimeit(unittest.TestCase): def test_main_verbose(self): s = self.run_main(switches=['-v']) self.assertEqual(s, dedent("""[](#l1.38)
10 loops -> 10 secs[](#l1.39)
raw times: 10 10 10[](#l1.40)
10 loops, best of 3: 1 sec per loop[](#l1.41)
1 loop -> 1 secs[](#l1.42)
raw times: 1 1 1[](#l1.43)
1 loop, best of 3: 1 sec per loop[](#l1.44) """))[](#l1.45)
def test_main_very_verbose(self): s = self.run_main(seconds_per_increment=0.000050, switches=['-vv']) self.assertEqual(s, dedent("""[](#l1.49)
1 loop -> 5e-05 secs[](#l1.50) 10 loops -> 0.0005 secs[](#l1.51) 100 loops -> 0.005 secs[](#l1.52) 1000 loops -> 0.05 secs[](#l1.53)
@@ -328,15 +329,15 @@ class TestTimeit(unittest.TestCase): unit_sec = self.run_main(seconds_per_increment=0.002, switches=['-u', 'sec']) self.assertEqual(unit_sec,
"1000 loops, best of 3: 0.002 sec per loop\n")[](#l1.58)
"100 loops, best of 3: 0.002 sec per loop\n")[](#l1.59) unit_msec = self.run_main(seconds_per_increment=0.002,[](#l1.60) switches=['-u', 'msec'])[](#l1.61) self.assertEqual(unit_msec,[](#l1.62)
"1000 loops, best of 3: 2 msec per loop\n")[](#l1.63)
"100 loops, best of 3: 2 msec per loop\n")[](#l1.64) unit_usec = self.run_main(seconds_per_increment=0.002,[](#l1.65) switches=['-u', 'usec'])[](#l1.66) self.assertEqual(unit_usec,[](#l1.67)
"1000 loops, best of 3: 2e+03 usec per loop\n")[](#l1.68)
"100 loops, best of 3: 2e+03 usec per loop\n")[](#l1.69) # Test invalid unit input[](#l1.70) with captured_stderr() as error_stringio:[](#l1.71) invalid = self.run_main(seconds_per_increment=0.002,[](#l1.72)
@@ -354,8 +355,8 @@ class TestTimeit(unittest.TestCase): s = self.run_main(switches=['-n1', '1/0']) self.assert_exc_string(error_stringio.getvalue(), 'ZeroDivisionError')
- def autorange(self, seconds_per_increment=0.001, callback=None):
timer = FakeTimer(seconds_per_increment=seconds_per_increment)[](#l1.80) t = timeit.Timer(stmt=self.fake_stmt, setup=self.fake_setup, timer=timer)[](#l1.81) return t.autorange(callback)[](#l1.82)
@@ -364,14 +365,20 @@ class TestTimeit(unittest.TestCase): self.assertEqual(num_loops, 1000) self.assertEqual(time_taken, 1.0)
- def test_autorange_second(self):
num_loops, time_taken = self.autorange(seconds_per_increment=1.0)[](#l1.89)
self.assertEqual(num_loops, 1)[](#l1.90)
self.assertEqual(time_taken, 1.0)[](#l1.91)
+ def test_autorange_with_callback(self): def callback(a, b): print("{} {:.3f}".format(a, b)) with captured_stdout() as s:
num_loops, time_taken = self.autorange(callback)[](#l1.97)
num_loops, time_taken = self.autorange(callback=callback)[](#l1.98) self.assertEqual(num_loops, 1000)[](#l1.99) self.assertEqual(time_taken, 1.0)[](#l1.100)
expected = ('10 0.010\n'[](#l1.101)
expected = ('1 0.001\n'[](#l1.102)
'10 0.010\n'[](#l1.103) '100 0.100\n'[](#l1.104) '1000 1.000\n')[](#l1.105) self.assertEqual(s.getvalue(), expected)[](#l1.106)
--- a/Lib/timeit.py
+++ b/Lib/timeit.py
@@ -218,7 +218,7 @@ class Timer:
If callback is given and is not None, it will be called after
each trial with two arguments: callback(number, time_taken)
.
"""
for i in range(1, 10):[](#l2.7)
for i in range(0, 10):[](#l2.8) number = 10**i[](#l2.9) time_taken = self.timeit(number)[](#l2.10) if callback:[](#l2.11)
@@ -318,8 +318,10 @@ def main(args=None, *, _wrap_timer=None) callback = None if verbose: def callback(number, time_taken):
msg = "{num} loops -> {secs:.{prec}g} secs"[](#l2.16)
print(msg.format(num=number, secs=time_taken, prec=precision))[](#l2.17)
msg = "{num} loop{s} -> {secs:.{prec}g} secs"[](#l2.18)
plural = (number != 1)[](#l2.19)
print(msg.format(num=number, s='s' if plural else '',[](#l2.20)
secs=time_taken, prec=precision))[](#l2.21) try:[](#l2.22) number, _ = t.autorange(callback)[](#l2.23) except:[](#l2.24)
@@ -333,7 +335,7 @@ def main(args=None, *, _wrap_timer=None) best = min(r) if verbose: print("raw times:", " ".join(["%.*g" % (precision, x) for x in r]))
- print("%d loop%s," % (number, 's' if number != 1 else ''), end=' ') usec = best * 1e6 / number if time_unit is not None: scale = units[time_unit]
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -88,6 +88,11 @@ Core and Builtins Library ------- +- Issue #28240: timeit autorange now uses a single loop iteration if the