Skip to content

Commit 23a1e85

Browse files
authored
Merge pull request #200 from seddonym/fix-cache-benchmarking-issues
Address issue with setting up the partial cache in benchmark
2 parents 23da102 + 3bfddd4 commit 23a1e85

2 files changed

Lines changed: 47 additions & 8 deletions

File tree

tests/benchmarking/adaptors.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from grimp.adaptors.caching import Cache, CacheMiss
2+
from typing import Set
3+
4+
from grimp.application.ports.modulefinder import ModuleFile
5+
from grimp.domain.valueobjects import DirectImport
6+
7+
8+
class PrefixMissingCache(Cache):
9+
"""
10+
Test double of the real cache that will miss caching any module that begins with
11+
a special prefix.
12+
"""
13+
14+
MISSING_PREFIX = "miss_marker_8772f06d64b6_" # Arbitrary prefix.
15+
16+
def read_imports(self, module_file: ModuleFile) -> Set[DirectImport]:
17+
leaf_name = module_file.module.name.split(".")[-1]
18+
if leaf_name.startswith(self.MISSING_PREFIX):
19+
raise CacheMiss
20+
return super().read_imports(module_file)

tests/benchmarking/test_benchmarking.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
import json
33
import importlib
44
from pathlib import Path
5+
6+
from tests.config import override_settings
57
from grimp.adaptors.graph import ImportGraph
68
from grimp import PackageDependency, Route
79
import grimp
810
from copy import deepcopy
11+
from .adaptors import PrefixMissingCache
912

1013

1114
def _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
)
322326
def 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

339358
class TestFindIllegalDependenciesForLayers:

0 commit comments

Comments
 (0)