22import json
33import importlib
44from pathlib import Path
5+
6+ from tests .config import override_settings
57from grimp .adaptors .graph import ImportGraph
68from grimp import PackageDependency , Route
79import grimp
810from copy import deepcopy
11+ from .adaptors import PrefixMissingCache
912
1013
1114def _run_benchmark (benchmark , fn , * args , ** kwargs ):
@@ -317,6 +320,7 @@ def test_build_django_from_cache_no_misses(benchmark):
317320 (
318321 2 , # Fewer than the likely number of CPUs.
319322 15 , # A bit more than the likely number of CPUs.
323+ 350 , # Around half the Django codebase.
320324 ),
321325)
322326def test_build_django_from_cache_a_few_misses (benchmark , number_of_misses ):
@@ -325,15 +329,30 @@ def test_build_django_from_cache_a_few_misses(benchmark, number_of_misses):
325329
326330 This benchmark utilizes the cache except for a few modules, which we add.
327331 """
328- # Populate the cache first, before beginning the benchmark.
329- grimp .build_graph ("django" )
330- # Add a module which won't be in the cache.
331- django_path = Path (importlib .util .find_spec ("django" ).origin ).parent
332- for i in range (number_of_misses ):
333- new_module = django_path / f"new_module_{ i } .py"
334- new_module .write_text ("from django.db import models" )
332+ # We must use a special cache class, otherwise the cache will be populated
333+ # by the first iteration. It would be better to do this using a setup function,
334+ # which is supported by pytest-benchmark's pedantic mode, but not codspeed.
335+ # This won't give us a truly accurate picture, but it's better than nothing.
335336
336- _run_benchmark (benchmark , grimp .build_graph , "django" )
337+ # Add some specially-named modules which will be treated as not in the cache.
338+ django_path = Path (importlib .util .find_spec ("django" ).origin ).parent
339+ extra_modules = [
340+ django_path / f"{ PrefixMissingCache .MISSING_PREFIX } { i } .py" for i in range (number_of_misses )
341+ ]
342+ # Use some real python, which will take time to parse.
343+ module_to_copy = django_path / "forms" / "forms.py"
344+ module_contents = module_to_copy .read_text ()
345+ for extra_module in extra_modules :
346+ extra_module .write_text (module_contents )
347+
348+ with override_settings (CACHE_CLASS = PrefixMissingCache ):
349+ # Populate the cache.
350+ grimp .build_graph ("django" )
351+
352+ _run_benchmark (benchmark , grimp .build_graph , "django" )
353+
354+ # Clean up.
355+ [module .unlink () for module in extra_modules ]
337356
338357
339358class TestFindIllegalDependenciesForLayers :
0 commit comments