From 4a42afdc2f3bb21f1685ac5c49b806ae34c36355 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Tue, 28 Apr 2020 22:26:54 +0300 Subject: [PATCH] cacheprovider: speed up NFPlugin when --nf is not enabled The code used an O(n^2) loop. Replace list with set to make it O(n). For backward compatibility the filesystem cache still remains a list. On this test: import pytest @pytest.mark.parametrize("x", range(5000)) def test_foo(x): pass run with `pytest --collect-only`: Before: 0m1.251s After: 0m0.921s --- src/_pytest/cacheprovider.py | 12 +++++------- testing/test_cacheprovider.py | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index 2f13067bc..133352262 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -332,13 +332,13 @@ class NFPlugin: def __init__(self, config): self.config = config self.active = config.option.newfirst - self.cached_nodeids = config.cache.get("cache/nodeids", []) + self.cached_nodeids = set(config.cache.get("cache/nodeids", [])) def pytest_collection_modifyitems( self, session: Session, config: Config, items: List[nodes.Item] ) -> None: - new_items = OrderedDict() # type: OrderedDict[str, nodes.Item] if self.active: + new_items = OrderedDict() # type: OrderedDict[str, nodes.Item] other_items = OrderedDict() # type: OrderedDict[str, nodes.Item] for item in items: if item.nodeid not in self.cached_nodeids: @@ -349,11 +349,9 @@ class NFPlugin: items[:] = self._get_increasing_order( new_items.values() ) + self._get_increasing_order(other_items.values()) + self.cached_nodeids.update(new_items) else: - for item in items: - if item.nodeid not in self.cached_nodeids: - new_items[item.nodeid] = item - self.cached_nodeids.extend(new_items) + self.cached_nodeids.update(item.nodeid for item in items) def _get_increasing_order(self, items): return sorted(items, key=lambda item: item.fspath.mtime(), reverse=True) @@ -363,7 +361,7 @@ class NFPlugin: if config.getoption("cacheshow") or hasattr(config, "slaveinput"): return - config.cache.set("cache/nodeids", self.cached_nodeids) + config.cache.set("cache/nodeids", sorted(self.cached_nodeids)) def pytest_addoption(parser): diff --git a/testing/test_cacheprovider.py b/testing/test_cacheprovider.py index eb381ab50..0b1ab6126 100644 --- a/testing/test_cacheprovider.py +++ b/testing/test_cacheprovider.py @@ -74,7 +74,7 @@ class TestNewAPI: "*/cacheprovider.py:*", " */cacheprovider.py:*: PytestCacheWarning: could not create cache path " "{}/v/cache/nodeids".format(cache_dir), - ' config.cache.set("cache/nodeids", self.cached_nodeids)', + ' config.cache.set("cache/nodeids", sorted(self.cached_nodeids))', "*1 failed, 3 warnings in*", ] )