summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeppe Fihl-Pearson <jeppe@tenzer.dk>2019-02-28 14:21:26 +0000
committerJeppe Fihl-Pearson <jeppe@tenzer.dk>2019-02-28 14:21:26 +0000
commit6e8389b5214a6ca5131dfe9ec3c48f842dd4b0a2 (patch)
tree72283f658e49f4a7d6ec6cc1a85fc58dd18913c7
parentf0badf18389935b0275660f8f3ef9899dc4c4f49 (diff)
downloadisort-6e8389b5214a6ca5131dfe9ec3c48f842dd4b0a2.tar.gz
Add LRU cache to RequirementsFinder._get_names
This caches the result of the function for future invocations with the same input, which can massively speed up future invocations if they have the same input as previous calls. In the case of this function this happens a lot, and each invocation is quite expensive as the requirements file is parsed every time. This gives a quite significant performance boost. I've tried running `isort` with and without this patch on two different applications on Python 3.7.2 and one one application the run time drops from 12.67 seconds to 1.3 seconds and on the other it drops from 28.29 seconds to 2.1 seconds. This optimisation is similiar to the one which was done for the 4.3.x branch here: https://github.com/timothycrosley/isort/pull/856.
-rw-r--r--isort/finders.py14
1 files changed, 12 insertions, 2 deletions
diff --git a/isort/finders.py b/isort/finders.py
index e21ef447..75a79951 100644
--- a/isort/finders.py
+++ b/isort/finders.py
@@ -8,6 +8,7 @@ import sys
import sysconfig
from abc import ABCMeta, abstractmethod
from fnmatch import fnmatch
+from functools import lru_cache
from glob import glob
from typing import Any, Dict, Iterable, Iterator, List, Mapping, Optional, Pattern, Sequence, Tuple, Type
@@ -288,14 +289,23 @@ class RequirementsFinder(ReqsBaseFinder):
yield full_path
break
- def _get_names(self, path: str) -> Iterator[str]:
+ def _get_names(self, path: str) -> List[str]:
"""Load required packages from path to requirements file
"""
+ return RequirementsFinder._get_names_cached(path)
+
+ @classmethod
+ @lru_cache(maxsize=16)
+ def _get_names_cached(cls, path: str) -> List[str]:
+ result = []
+
with chdir(os.path.dirname(path)):
requirements = parse_requirements(path, session=PipSession())
for req in requirements:
if req.name:
- yield req.name
+ result.append(req.name)
+
+ return result
class PipfileFinder(ReqsBaseFinder):