Skip to content

Avoid repeated Element dependency graph traversal #2176

Open

Description

@kotborealis

Element.__update_cache_keys() may traverse the same BUILD dependency graph multiple times while calculating weak and strict cache keys.
PR #2172 reduces this locally by materializing the dependency list once and reusing it for both calculations, but Element._dependencies() could be cached with something like @functools.cache.

Activity

  1. nathanwilliams-ct commented on Aug 17, 2026

    @nathanwilliams-ct
    Contributor

    From comment thread:
    """
    hmm.. Instead of storing the result of _dependencies here, it might be worth refactoring _dependencies to directly cache it's own results, so it can return the cached result after the first call, whenever it's called anywhere instead of just here. I don't think __build_dependencies or __runtime_dependencies is ever updated after an Element is first initialised in _new_from_load_element. (Although _add_build_dependency might be a problem? that would need investigating, but you could clear the cache, in that method..)

    ...
      __dependency_set_cache: dict[str,set[Element]] = {}
    
    def __dependencies(...) -> ...:
    
      # Check if we already calculated this set of dependencies
      dependency_set_cache_key = f"{scope}, {recurse}" # (probably need to include the _dependencies 'visited' argument here too...)
      if (dependencies := self.__dependency_set_cache.get(dependency_set_cache_key)) is not None:
         for element in dependencies:
           yield element
         return
      
       # Calculate result/visited
       .... 
    
    
       # Store result for next time
       self.__build_dependencies_set[dependency_set_cache_key] = result # ( or 'visited' from the recursive visit function)
    
    

    It will need some thinking, but maybe it would even be appropriate to use functools @cache annotation? https://docs.python.org/3/library/functools.html The recursive visit function might also benefit from the @cache annotation..
    """

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions