Skip to content

Commit 8db5b54

Browse files
authored
bpo-35513, unittest: TextTestRunner uses time.perf_counter() (GH-11180)
TextTestRunner of unittest.runner now uses time.perf_counter() rather than time.time() to measure the execution time of a test: time.time() can go backwards, whereas time.perf_counter() is monotonic. Similar change made in libregrtest, pprint and random.
1 parent 2cf4c20 commit 8db5b54

File tree

6 files changed

+19
-15
lines changed

6 files changed

+19
-15
lines changed

Lib/pprint.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -568,11 +568,11 @@ def _perfcheck(object=None):
568568
if object is None:
569569
object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000
570570
p = PrettyPrinter()
571-
t1 = time.time()
571+
t1 = time.perf_counter()
572572
_safe_repr(object, {}, None, 0)
573-
t2 = time.time()
573+
t2 = time.perf_counter()
574574
p.pformat(object)
575-
t3 = time.time()
575+
t3 = time.perf_counter()
576576
print("_safe_repr:", t2 - t1)
577577
print("pformat:", t3 - t2)
578578

Lib/random.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -740,14 +740,14 @@ def _test_generator(n, func, args):
740740
sqsum = 0.0
741741
smallest = 1e10
742742
largest = -1e10
743-
t0 = time.time()
743+
t0 = time.perf_counter()
744744
for i in range(n):
745745
x = func(*args)
746746
total += x
747747
sqsum = sqsum + x*x
748748
smallest = min(x, smallest)
749749
largest = max(x, largest)
750-
t1 = time.time()
750+
t1 = time.perf_counter()
751751
print(round(t1-t0, 3), 'sec,', end=' ')
752752
avg = total/n
753753
stddev = _sqrt(sqsum/n - avg*avg)

Lib/test/libregrtest/runtest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def runtest_inner(ns, test, display_failure=True):
162162
abstest = get_abs_module(ns, test)
163163
clear_caches()
164164
with saved_test_environment(test, ns.verbose, ns.quiet, pgo=ns.pgo) as environment:
165-
start_time = time.time()
165+
start_time = time.perf_counter()
166166
the_module = importlib.import_module(abstest)
167167
# If the test has a test_main, that will run the appropriate
168168
# tests. If not, use normal unittest test loading.
@@ -180,7 +180,7 @@ def test_runner():
180180
refleak = dash_R(the_module, test, test_runner, ns.huntrleaks)
181181
else:
182182
test_runner()
183-
test_time = time.time() - start_time
183+
test_time = time.perf_counter() - start_time
184184
post_test_cleanup()
185185
except support.ResourceDenied as msg:
186186
if not ns.quiet and not ns.pgo:

Lib/test/time_hashlib.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,26 @@ def test_scaled_msg(scale, name):
1414
longStr = b'Z'*scale
1515

1616
localCF = creatorFunc
17-
start = time.time()
17+
start = time.perf_counter()
1818
for f in range(iterations):
1919
x = localCF(longStr).digest()
20-
end = time.time()
20+
end = time.perf_counter()
2121

2222
print(('%2.2f' % (end-start)), "seconds", iterations, "x", len(longStr), "bytes", name)
2323

2424
def test_create():
25-
start = time.time()
25+
start = time.perf_counter()
2626
for f in range(20000):
2727
d = creatorFunc()
28-
end = time.time()
28+
end = time.perf_counter()
2929

3030
print(('%2.2f' % (end-start)), "seconds", '[20000 creations]')
3131

3232
def test_zero():
33-
start = time.time()
33+
start = time.perf_counter()
3434
for f in range(20000):
3535
x = creatorFunc().digest()
36-
end = time.time()
36+
end = time.perf_counter()
3737

3838
print(('%2.2f' % (end-start)), "seconds", '[20000 "" digests]')
3939

Lib/unittest/runner.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def run(self, test):
168168
warnings.filterwarnings('module',
169169
category=DeprecationWarning,
170170
message=r'Please use assert\w+ instead.')
171-
startTime = time.time()
171+
startTime = time.perf_counter()
172172
startTestRun = getattr(result, 'startTestRun', None)
173173
if startTestRun is not None:
174174
startTestRun()
@@ -178,7 +178,7 @@ def run(self, test):
178178
stopTestRun = getattr(result, 'stopTestRun', None)
179179
if stopTestRun is not None:
180180
stopTestRun()
181-
stopTime = time.time()
181+
stopTime = time.perf_counter()
182182
timeTaken = stopTime - startTime
183183
result.printErrors()
184184
if hasattr(result, 'separator2'):
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
:class:`~unittest.runner.TextTestRunner` of :mod:`unittest.runner` now uses
2+
:func:`time.perf_counter` rather than :func:`time.time` to measure the
3+
execution time of a test: :func:`time.time` can go backwards, whereas
4+
:func:`time.perf_counter` is monotonic.

0 commit comments

Comments
 (0)