1 |
Each of these functions is called repeatedly with the same arguments |
2 |
many times. Cache sizes were selected to minimize memory use increase, |
3 |
while still providing about the same speedup compared to a cache with |
4 |
unbounded size. "emerge -uDvpU --with-bdeps=y @world" runtime decreases |
5 |
from 44.32s -> 29.94s -- a 48% speedup, while the maximum value of the |
6 |
RES column in htop increases from 280 MB -> 290 MB. |
7 |
|
8 |
"emerge -ep @world" time slightly decreases from 18.77s -> 17.93, while |
9 |
max observed RES value actually decreases from 228 MB -> 214 MB (similar |
10 |
values observed across a few before/after runs). |
11 |
--- |
12 |
lib/portage/dep/__init__.py | 107 +++++++++++++++++++++--------------- |
13 |
lib/portage/versions.py | 3 + |
14 |
2 files changed, 67 insertions(+), 43 deletions(-) |
15 |
|
16 |
diff --git a/lib/portage/dep/__init__.py b/lib/portage/dep/__init__.py |
17 |
index 72988357a..314338f7c 100644 |
18 |
--- a/lib/portage/dep/__init__.py |
19 |
+++ b/lib/portage/dep/__init__.py |
20 |
@@ -17,6 +17,7 @@ __all__ = [ |
21 |
|
22 |
import re, sys |
23 |
import warnings |
24 |
+from functools import lru_cache |
25 |
|
26 |
import portage |
27 |
portage.proxy.lazyimport.lazyimport(globals(), |
28 |
@@ -404,49 +405,10 @@ def paren_enclose(mylist, unevaluated_atom=False, opconvert=False): |
29 |
mystrparts.append(x) |
30 |
return " ".join(mystrparts) |
31 |
|
32 |
-def use_reduce(depstr, uselist=(), masklist=(), matchall=False, excludeall=(), is_src_uri=False, \ |
33 |
- eapi=None, opconvert=False, flat=False, is_valid_flag=None, token_class=None, matchnone=False, |
34 |
- subset=None): |
35 |
- """ |
36 |
- Takes a dep string and reduces the use? conditionals out, leaving an array |
37 |
- with subarrays. All redundant brackets are removed. |
38 |
- |
39 |
- @param depstr: depstring |
40 |
- @type depstr: String |
41 |
- @param uselist: Sequence of use enabled flags |
42 |
- @type uselist: Sequence |
43 |
- @param masklist: Sequence of masked flags (always treated as disabled) |
44 |
- @type masklist: Sequence |
45 |
- @param matchall: Treat all conditionals as active. Used by repoman. |
46 |
- @type matchall: Bool |
47 |
- @param excludeall: Sequence of flags for which negated conditionals are always treated as inactive. |
48 |
- @type excludeall: Sequence |
49 |
- @param is_src_uri: Indicates if depstr represents a SRC_URI |
50 |
- @type is_src_uri: Bool |
51 |
- @param eapi: Indicates the EAPI the dep string has to comply to |
52 |
- @type eapi: String |
53 |
- @param opconvert: Put every operator as first element into it's argument list |
54 |
- @type opconvert: Bool |
55 |
- @param flat: Create a flat list of all tokens |
56 |
- @type flat: Bool |
57 |
- @param is_valid_flag: Function that decides if a given use flag might be used in use conditionals |
58 |
- @type is_valid_flag: Function |
59 |
- @param token_class: Convert all non operator tokens into this class |
60 |
- @type token_class: Class |
61 |
- @param matchnone: Treat all conditionals as inactive. Used by digestgen(). |
62 |
- @type matchnone: Bool |
63 |
- @param subset: Select a subset of dependencies conditional on the given flags |
64 |
- @type subset: Sequence |
65 |
- @rtype: List |
66 |
- @return: The use reduced depend array |
67 |
- """ |
68 |
- if isinstance(depstr, list): |
69 |
- if portage._internal_caller: |
70 |
- warnings.warn(_("Passing paren_reduced dep arrays to %s is deprecated. " + \ |
71 |
- "Pass the original dep string instead.") % \ |
72 |
- ('portage.dep.use_reduce',), DeprecationWarning, stacklevel=2) |
73 |
- depstr = paren_enclose(depstr) |
74 |
- |
75 |
+@lru_cache(1024) |
76 |
+def _use_reduce_cached(depstr, uselist, masklist, matchall, excludeall, \ |
77 |
+ is_src_uri, eapi, opconvert, flat, is_valid_flag, token_class, \ |
78 |
+ matchnone,subset): |
79 |
if opconvert and flat: |
80 |
raise ValueError("portage.dep.use_reduce: 'opconvert' and 'flat' are mutually exclusive") |
81 |
|
82 |
@@ -769,6 +731,65 @@ def use_reduce(depstr, uselist=(), masklist=(), matchall=False, excludeall=(), i |
83 |
|
84 |
return stack[0] |
85 |
|
86 |
+def use_reduce(depstr, uselist=(), masklist=(), matchall=False, excludeall=(), is_src_uri=False, \ |
87 |
+ eapi=None, opconvert=False, flat=False, is_valid_flag=None, token_class=None, matchnone=False, |
88 |
+ subset=None): |
89 |
+ """ |
90 |
+ Takes a dep string and reduces the use? conditionals out, leaving an array |
91 |
+ with subarrays. All redundant brackets are removed. |
92 |
+ |
93 |
+ @param depstr: depstring |
94 |
+ @type depstr: String |
95 |
+ @param uselist: Sequence of use enabled flags |
96 |
+ @type uselist: Sequence |
97 |
+ @param masklist: Sequence of masked flags (always treated as disabled) |
98 |
+ @type masklist: Sequence |
99 |
+ @param matchall: Treat all conditionals as active. Used by repoman. |
100 |
+ @type matchall: Bool |
101 |
+ @param excludeall: Sequence of flags for which negated conditionals are always treated as inactive. |
102 |
+ @type excludeall: Sequence |
103 |
+ @param is_src_uri: Indicates if depstr represents a SRC_URI |
104 |
+ @type is_src_uri: Bool |
105 |
+ @param eapi: Indicates the EAPI the dep string has to comply to |
106 |
+ @type eapi: String |
107 |
+ @param opconvert: Put every operator as first element into it's argument list |
108 |
+ @type opconvert: Bool |
109 |
+ @param flat: Create a flat list of all tokens |
110 |
+ @type flat: Bool |
111 |
+ @param is_valid_flag: Function that decides if a given use flag might be used in use conditionals |
112 |
+ @type is_valid_flag: Function |
113 |
+ @param token_class: Convert all non operator tokens into this class |
114 |
+ @type token_class: Class |
115 |
+ @param matchnone: Treat all conditionals as inactive. Used by digestgen(). |
116 |
+ @type matchnone: Bool |
117 |
+ @param subset: Select a subset of dependencies conditional on the given flags |
118 |
+ @type subset: Sequence |
119 |
+ @rtype: List |
120 |
+ @return: The use reduced depend array |
121 |
+ """ |
122 |
+ if isinstance(depstr, list): |
123 |
+ if portage._internal_caller: |
124 |
+ warnings.warn(_("Passing paren_reduced dep arrays to %s is deprecated. " + \ |
125 |
+ "Pass the original dep string instead.") % \ |
126 |
+ ('portage.dep.use_reduce',), DeprecationWarning, stacklevel=2) |
127 |
+ depstr = paren_enclose(depstr) |
128 |
+ |
129 |
+ if uselist is not None: |
130 |
+ uselist = frozenset(uselist) |
131 |
+ if masklist is not None: |
132 |
+ masklist = frozenset(masklist) |
133 |
+ if excludeall is not None: |
134 |
+ excludeall = frozenset(excludeall) |
135 |
+ if subset is not None: |
136 |
+ subset = frozenset(subset) |
137 |
+ |
138 |
+ result = _use_reduce_cached(depstr, uselist, masklist, matchall, \ |
139 |
+ excludeall, is_src_uri, eapi, opconvert, flat, is_valid_flag, \ |
140 |
+ token_class, matchnone, subset) |
141 |
+ |
142 |
+ # The list returned by this function may be modified, so return a copy. |
143 |
+ return result[:] |
144 |
+ |
145 |
def dep_opconvert(deplist): |
146 |
""" |
147 |
Iterate recursively through a list of deps, if the |
148 |
diff --git a/lib/portage/versions.py b/lib/portage/versions.py |
149 |
index 0c21373cc..100c8b84d 100644 |
150 |
--- a/lib/portage/versions.py |
151 |
+++ b/lib/portage/versions.py |
152 |
@@ -13,6 +13,7 @@ __all__ = [ |
153 |
import re |
154 |
import sys |
155 |
import warnings |
156 |
+from functools import lru_cache |
157 |
|
158 |
if sys.hexversion < 0x3000000: |
159 |
_unicode = unicode |
160 |
@@ -116,6 +117,7 @@ def ververify(myver, silent=1): |
161 |
print(_("!!! syntax error in version: %s") % myver) |
162 |
return False |
163 |
|
164 |
+@lru_cache(1024) |
165 |
def vercmp(ver1, ver2, silent=1): |
166 |
""" |
167 |
Compare two versions |
168 |
@@ -313,6 +315,7 @@ def _pkgsplit(mypkg, eapi=None): |
169 |
_cat_re = re.compile('^%s$' % _cat, re.UNICODE) |
170 |
_missing_cat = 'null' |
171 |
|
172 |
+@lru_cache(10240) |
173 |
def catpkgsplit(mydata, silent=1, eapi=None): |
174 |
""" |
175 |
Takes a Category/Package-Version-Rev and returns a list of each. |
176 |
-- |
177 |
2.27.0.389.gc38d7665816-goog |