diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py
index 361189199d3820..d6e5031c771d07 100644
--- a/Lib/test/libregrtest/main.py
+++ b/Lib/test/libregrtest/main.py
@@ -12,7 +12,7 @@
 from test.libregrtest.cmdline import _parse_args
 from test.libregrtest.runtest import (
     findtests, runtest, get_abs_module, is_failed,
-    STDTESTS, NOTTESTS, PROGRESS_MIN_TIME,
+    PROGRESS_MIN_TIME,
     Passed, Failed, EnvChanged, Skipped, ResourceDenied, Interrupted,
     ChildError, DidNotRun)
 from test.libregrtest.setup import setup_tests
@@ -42,6 +42,32 @@
 EXITCODE_ENV_CHANGED = 3
 EXITCODE_NO_TESTS_RAN = 4
 
+# Coarse heuristic: tests taking at least 1 minute on a modern
+# developer laptop. The list should have less than 20 tests.
+SLOWEST_TESTS = frozenset((
+    # more or less sorted from the slowest to the fastest
+    "test_concurrent_futures",
+    "test_multiprocessing_spawn",
+    "test_multiprocessing_forkserver",
+    "test_multiprocessing_fork",
+    "test_multiprocessing_main_handling",
+    "test_pickle",
+    "test_compileall",
+    "test_cppext",
+    "test_venv",
+    "test_gdb",
+    "test_tools",
+    "test_peg_generator",
+    "test_perf_profiler",
+    "test_buffer",
+    "test_subprocess",
+    "test_signal",
+    "test_tarfile",
+    "test_regrtest",
+    "test_socket",
+    "test_io",
+))
+
 
 class Regrtest:
     """Execute a test suite.
@@ -246,21 +272,18 @@ def find_tests(self, tests):
             # add default PGO tests if no tests are specified
             setup_pgo_tests(self.ns)
 
-        stdtests = STDTESTS[:]
-        nottests = NOTTESTS.copy()
+        exclude_tests = set()
         if self.ns.exclude:
             for arg in self.ns.args:
-                if arg in stdtests:
-                    stdtests.remove(arg)
-                nottests.add(arg)
+                exclude_tests.add(arg)
             self.ns.args = []
 
         # if testdir is set, then we are not running the python tests suite, so
         # don't add default tests to be executed or skipped (pass empty values)
         if self.ns.testdir:
-            alltests = findtests(self.ns.testdir, list(), set())
+            alltests = findtests(self.ns.testdir)
         else:
-            alltests = findtests(self.ns.testdir, stdtests, nottests)
+            alltests = findtests(self.ns.testdir, exclude=exclude_tests)
 
         if not self.ns.fromfile:
             self.selected = self.tests or self.ns.args or alltests
@@ -282,11 +305,31 @@ def find_tests(self, tests):
                 print("Couldn't find starting test (%s), using all tests"
                       % self.ns.start, file=sys.stderr)
 
+        self.group_randomize_tests()
+
+    def group_randomize_tests(self):
         if self.ns.randomize:
             if self.ns.random_seed is None:
                 self.ns.random_seed = random.randrange(10000000)
             random.seed(self.ns.random_seed)
-            random.shuffle(self.selected)
+
+        # group slow tests
+        slow = []
+        other = []
+        for name in self.selected:
+            if name in SLOWEST_TESTS:
+                slow.append(name)
+            else:
+                other.append(name)
+
+        if self.ns.randomize:
+            if slow:
+                random.shuffle(slow)
+            if other:
+                random.shuffle(other)
+
+        # gh-108388: Run the slowest first, and then other tests
+        self.selected = slow + other
 
     def list_tests(self):
         for name in self.selected:
@@ -420,8 +463,8 @@ def display_result(self):
         if self.ns.print_slow:
             self.test_times.sort(reverse=True)
             print()
-            print("10 slowest tests:")
-            for test_time, test in self.test_times[:10]:
+            print("20 slowest tests:")
+            for test_time, test in self.test_times[:20]:
                 print("- %s: %s" % (test, format_duration(test_time)))
 
         if self.bad:
diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py
index 61595277ed6d5a..9cc1ab7a9c389e 100644
--- a/Lib/test/libregrtest/runtest.py
+++ b/Lib/test/libregrtest/runtest.py
@@ -125,24 +125,6 @@ def __str__(self) -> str:
 # the test is running in background
 PROGRESS_MIN_TIME = 30.0   # seconds
 
-# small set of tests to determine if we have a basically functioning interpreter
-# (i.e. if any of these fail, then anything else is likely to follow)
-STDTESTS = [
-    'test_grammar',
-    'test_opcodes',
-    'test_dict',
-    'test_builtin',
-    'test_exceptions',
-    'test_types',
-    'test_unittest',
-    'test_doctest',
-    'test_doctest2',
-    'test_support'
-]
-
-# set of tests that we don't want to be executed when using regrtest
-NOTTESTS = set()
-
 #If these test directories are encountered recurse into them and treat each
 # test_ .py or dir as a separate test module. This can increase parallelism.
 # Beware this can't generally be done for any directory with sub-tests as the
@@ -166,22 +148,23 @@ def findtestdir(path=None):
     return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir
 
 
-def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS, *, split_test_dirs=SPLITTESTDIRS, base_mod=""):
+def findtests(testdir=None, *, exclude=(), split_test_dirs=SPLITTESTDIRS, base_mod=""):
     """Return a list of all applicable test modules."""
     testdir = findtestdir(testdir)
     names = os.listdir(testdir)
     tests = []
-    others = set(stdtests) | nottests
     for name in names:
         mod, ext = os.path.splitext(name)
-        if mod[:5] == "test_" and mod not in others:
-            if mod in split_test_dirs:
-                subdir = os.path.join(testdir, mod)
-                mod = f"{base_mod or 'test'}.{mod}"
-                tests.extend(findtests(subdir, [], nottests, split_test_dirs=split_test_dirs, base_mod=mod))
-            elif ext in (".py", ""):
-                tests.append(f"{base_mod}.{mod}" if base_mod else mod)
-    return stdtests + sorted(tests)
+        if not mod.startswith("test_") or mod in exclude:
+            continue
+
+        if mod in split_test_dirs:
+            subdir = os.path.join(testdir, mod)
+            mod = f"{base_mod or 'test'}.{mod}"
+            tests.extend(findtests(subdir, exclude=exclude, split_test_dirs=split_test_dirs, base_mod=mod))
+        elif ext in (".py", ""):
+            tests.append(f"{base_mod}.{mod}" if base_mod else mod)
+    return sorted(tests)
 
 
 def get_abs_module(ns: Namespace, test_name: str) -> str:
diff --git a/Lib/test/test_peg_generator/__init__.py b/Lib/test/test_peg_generator/__init__.py
index c23542e254c99f..87281eb5e03c7f 100644
--- a/Lib/test/test_peg_generator/__init__.py
+++ b/Lib/test/test_peg_generator/__init__.py
@@ -4,8 +4,10 @@
 from test.support import load_package_tests
 
 
-# Creating a virtual environment and building C extensions is slow
-support.requires('cpu')
+if support.check_sanitizer(address=True, memory=True):
+    # gh-90791: Skip the test because it is too slow when Python is built
+    # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions.
+    raise unittest.SkipTest("test too slow on ASAN/MSAN build")
 
 
 # Load all tests in package
diff --git a/Lib/test/test_tools/__init__.py b/Lib/test/test_tools/__init__.py
index c4395c7c0ad0c9..dde5d84e9edc6b 100644
--- a/Lib/test/test_tools/__init__.py
+++ b/Lib/test/test_tools/__init__.py
@@ -7,6 +7,12 @@
 from test.support import import_helper
 
 
+if support.check_sanitizer(address=True, memory=True):
+    # gh-90791: Skip the test because it is too slow when Python is built
+    # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions.
+    raise unittest.SkipTest("test too slow on ASAN/MSAN build")
+
+
 if not support.has_subprocess_support:
     raise unittest.SkipTest("test module requires subprocess")
 
diff --git a/Lib/test/test_tools/test_freeze.py b/Lib/test/test_tools/test_freeze.py
index 3e9a48b5bc6a89..2ba36ca208f967 100644
--- a/Lib/test/test_tools/test_freeze.py
+++ b/Lib/test/test_tools/test_freeze.py
@@ -18,9 +18,6 @@
 class TestFreeze(unittest.TestCase):
 
     def test_freeze_simple_script(self):
-        # Building Python is slow
-        support.requires('cpu')
-
         script = textwrap.dedent("""
             import sys
             print('running...')
diff --git a/Misc/NEWS.d/next/Tests/2023-08-24-02-36-15.gh-issue-108388.Z08JFZ.rst b/Misc/NEWS.d/next/Tests/2023-08-24-02-36-15.gh-issue-108388.Z08JFZ.rst
new file mode 100644
index 00000000000000..11980539ba360b
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2023-08-24-02-36-15.gh-issue-108388.Z08JFZ.rst
@@ -0,0 +1,3 @@
+The Python test suite (regrtest) now runs the 20 slowest tests first and
+then other tests, to better use all available CPUs when running tests in
+parallel. Patch Victor Stinner.