Skip to content

Commit 0387c34

Browse files
authored
gh-124402: Speed up test_free_threading and test_super (#124491)
* Reduce the number of iterations and the number of threads so a whole test file takes less than a minute. * Refactor test_racing_iter_extend() to remove two levels of indentation. * test_monitoring() uses a sleep of 100 ms instead of 1 second.
1 parent 08a467b commit 0387c34

File tree

4 files changed

+41
-53
lines changed

4 files changed

+41
-53
lines changed

Lib/test/test_free_threading/test_list.py

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,22 @@
33
from threading import Thread
44
from unittest import TestCase
55

6-
from test import support
76
from test.support import threading_helper
87

98

9+
NTHREAD = 10
10+
OBJECT_COUNT = 5_000
11+
12+
1013
class C:
1114
def __init__(self, v):
1215
self.v = v
1316

1417

1518
@threading_helper.requires_working_threading()
1619
class TestList(TestCase):
17-
@support.requires_resource('cpu')
1820
def test_racing_iter_append(self):
19-
2021
l = []
21-
OBJECT_COUNT = 10000
2222

2323
def writer_func():
2424
for i in range(OBJECT_COUNT):
@@ -34,7 +34,7 @@ def reader_func():
3434

3535
writer = Thread(target=writer_func)
3636
readers = []
37-
for x in range(30):
37+
for x in range(NTHREAD):
3838
reader = Thread(target=reader_func)
3939
readers.append(reader)
4040
reader.start()
@@ -44,39 +44,32 @@ def reader_func():
4444
for reader in readers:
4545
reader.join()
4646

47-
@support.requires_resource('cpu')
4847
def test_racing_iter_extend(self):
49-
iters = [
50-
lambda x: [x],
51-
]
52-
for iter_case in iters:
53-
with self.subTest(iter=iter_case):
54-
l = []
55-
OBJECT_COUNT = 10000
56-
57-
def writer_func():
58-
for i in range(OBJECT_COUNT):
59-
l.extend(iter_case(C(i + OBJECT_COUNT)))
60-
61-
def reader_func():
62-
while True:
63-
count = len(l)
64-
for i, x in enumerate(l):
65-
self.assertEqual(x.v, i + OBJECT_COUNT)
66-
if count == OBJECT_COUNT:
67-
break
68-
69-
writer = Thread(target=writer_func)
70-
readers = []
71-
for x in range(30):
72-
reader = Thread(target=reader_func)
73-
readers.append(reader)
74-
reader.start()
75-
76-
writer.start()
77-
writer.join()
78-
for reader in readers:
79-
reader.join()
48+
l = []
49+
50+
def writer_func():
51+
for i in range(OBJECT_COUNT):
52+
l.extend([C(i + OBJECT_COUNT)])
53+
54+
def reader_func():
55+
while True:
56+
count = len(l)
57+
for i, x in enumerate(l):
58+
self.assertEqual(x.v, i + OBJECT_COUNT)
59+
if count == OBJECT_COUNT:
60+
break
61+
62+
writer = Thread(target=writer_func)
63+
readers = []
64+
for x in range(NTHREAD):
65+
reader = Thread(target=reader_func)
66+
readers.append(reader)
67+
reader.start()
68+
69+
writer.start()
70+
writer.join()
71+
for reader in readers:
72+
reader.join()
8073

8174

8275
if __name__ == "__main__":

Lib/test/test_free_threading/test_monitoring.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@
77
import weakref
88

99
from sys import monitoring
10-
from test import support
1110
from test.support import threading_helper
1211
from threading import Thread, _PyRLock
1312
from unittest import TestCase
1413

1514

1615
class InstrumentationMultiThreadedMixin:
1716
thread_count = 10
18-
func_count = 200
17+
func_count = 50
1918
fib = 12
2019

2120
def after_threads(self):
@@ -37,14 +36,13 @@ def work(self, n, funcs):
3736
def start_work(self, n, funcs):
3837
# With the GIL builds we need to make sure that the hooks have
3938
# a chance to run as it's possible to run w/o releasing the GIL.
40-
time.sleep(1)
39+
time.sleep(0.1)
4140
self.work(n, funcs)
4241

4342
def after_test(self):
4443
"""Runs once after the test is done"""
4544
pass
4645

47-
@support.requires_resource('cpu')
4846
def test_instrumentation(self):
4947
# Setup a bunch of functions which will need instrumentation...
5048
funcs = []
@@ -220,29 +218,31 @@ def test_register_callback(self):
220218
for ref in self.refs:
221219
self.assertEqual(ref(), None)
222220

223-
@support.requires_resource('cpu')
224221
def test_set_local_trace_opcodes(self):
225222
def trace(frame, event, arg):
226223
frame.f_trace_opcodes = True
227224
return trace
228225

226+
loops = 1_000
227+
229228
sys.settrace(trace)
230229
try:
231230
l = _PyRLock()
232231

233232
def f():
234-
for i in range(3000):
233+
for i in range(loops):
235234
with l:
236235
pass
237236

238237
t = Thread(target=f)
239238
t.start()
240-
for i in range(3000):
239+
for i in range(loops):
241240
with l:
242241
pass
243242
t.join()
244243
finally:
245244
sys.settrace(None)
246245

246+
247247
if __name__ == "__main__":
248248
unittest.main()

Lib/test/test_free_threading/test_type.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from threading import Thread
66
from unittest import TestCase
77

8-
from test import support
98
from test.support import threading_helper
109

1110

@@ -97,8 +96,9 @@ def reader_func():
9796

9897
self.run_one(writer_func, reader_func)
9998

100-
@support.requires_resource('cpu')
10199
def test___class___modification(self):
100+
loops = 200
101+
102102
class Foo:
103103
pass
104104

@@ -108,7 +108,7 @@ class Bar:
108108
thing = Foo()
109109
def work():
110110
foo = thing
111-
for _ in range(5000):
111+
for _ in range(loops):
112112
foo.__class__ = Bar
113113
type(foo)
114114
foo.__class__ = Foo

Lib/test/test_super.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import threading
55
import unittest
66
from unittest.mock import patch
7-
from test import support
87
from test.support import import_helper, threading_helper
98

109

@@ -515,10 +514,6 @@ def test___class___modification_multithreaded(self):
515514
an audit hook.
516515
"""
517516

518-
if support.Py_GIL_DISABLED:
519-
# gh-124402: On a Free Threaded build, the test takes a few minutes
520-
support.requires('cpu')
521-
522517
class Foo:
523518
pass
524519

@@ -528,7 +523,7 @@ class Bar:
528523
thing = Foo()
529524
def work():
530525
foo = thing
531-
for _ in range(5000):
526+
for _ in range(200):
532527
foo.__class__ = Bar
533528
type(foo)
534529
foo.__class__ = Foo

0 commit comments

Comments
 (0)