[PATCH 2/3] Add caching to use_reduce function

Chun-Yu Shei <[email protected]>
Newsgroups gmane.linux.gentoo.portage.devel
Message-ID <[email protected]>
This function is called extremely frequently with similar arguments, so
this optimization reduces "emerge -uDvpU --with-bdeps=y @world" runtime from
43.5 -> 34.5s -- a 25.8% speedup.
---
 lib/portage/dep/__init__.py | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/lib/portage/dep/__init__.py b/lib/portage/dep/__init__.py
index 72988357a..df296dd81 100644
--- a/lib/portage/dep/__init__.py
+++ b/lib/portage/dep/__init__.py
@@ -404,6 +404,8 @@ def paren_enclose(mylist, unevaluated_atom=False, opconvert=False):
 			mystrparts.append(x)
 	return " ".join(mystrparts)
 
+_use_reduce_cache = {}
+
 def use_reduce(depstr, uselist=(), masklist=(), matchall=False, excludeall=(), is_src_uri=False, \
 	eapi=None, opconvert=False, flat=False, is_valid_flag=None, token_class=None, matchnone=False,
 	subset=None):
@@ -440,6 +442,27 @@ def use_reduce(depstr, uselist=(), masklist=(), matchall=False, excludeall=(), i
 	@rtype: List
 	@return: The use reduced depend array
 	"""
+	uselist_key = None
+	masklist_key = None
+	excludeall_key = None
+	subset_key = None
+	if uselist is not None:
+	    uselist_key = tuple(uselist)
+	if masklist is not None:
+	    masklist_key = tuple(masklist)
+	if excludeall is not None:
+	    excludeall_key = tuple(excludeall)
+	if subset is not None:
+	    subset_key = tuple(subset)
+	cache_key = (depstr, uselist_key, masklist_key, matchall, excludeall_key, \
+		is_src_uri, eapi, opconvert, flat, is_valid_flag, token_class, \
+		matchnone, subset_key)
+
+	cache_entry = _use_reduce_cache.get(cache_key)
+	if cache_entry is not None:
+		# The list returned by this function may be modified, so return a copy.
+		return cache_entry[:]
+
 	if isinstance(depstr, list):
 		if portage._internal_caller:
 			warnings.warn(_("Passing paren_reduced dep arrays to %s is deprecated. " + \
@@ -767,6 +790,9 @@ def use_reduce(depstr, uselist=(), masklist=(), matchall=False, excludeall=(), i
 		raise InvalidDependString(
 			_("Missing file name at end of string"))
 
+	# The list returned by this function may be modified, so store a copy.
+	_use_reduce_cache[cache_key] = stack[0][:]
+
 	return stack[0]
 
 def dep_opconvert(deplist):
-- 
2.27.0.212.ge8ba1cc988-goog
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.