Skip to content

feat: Add Caching for ElementUtil#140

Merged
lqiu96 merged 7 commits intogoogleapis:mainfrom
lqiu96:add_element_cache
Jul 27, 2022
Merged

feat: Add Caching for ElementUtil#140
lqiu96 merged 7 commits intogoogleapis:mainfrom
lqiu96:add_element_cache

Conversation

@lqiu96
Copy link
Copy Markdown
Member

@lqiu96 lqiu96 commented Jul 21, 2022

Fixes #126

Running the kokoro script with the updated element caching (no concurrency)
image
image
image

Seems the jobs without concurrency takes ~90 minutes. This is without running mvn clean install (which may take ~30 minutes/ ~12 minutes with -T 1C). Since the mvn javadoc:aggregate job needs to run mvn compile, do we need to have the have it clean install?

I don't think we would run into any memory issues. I can try to reduce the initial capacity since we're no longer running this for the entire monorepo (only for each submodule in the monorepo).

Both these changes were part of the initial debugging with YourKit profiler. The concurrent code calling getEnclosedElements() would need to be synchronized between the different threads. They were making the same call to element.getEnclosedElements() (https://docs.oracle.com/javase/7/docs/api/javax/lang/model/element/Element.html#getEnclosedElements()) but the result for this function doesn't change. Adding a map/cache to store the already computed values.

  • Tests pass
  • Appropriate changes to README are included in PR


private Map<String, String> globalLookup = new HashMap<>();
private Map<String, Map<String, String>> localLookupByFileName = new HashMap<>();
private static final int INITIAL_CAPACITY = 10000;
Copy link
Copy Markdown
Member Author

@lqiu96 lqiu96 Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set large initial map capacity to try to reduce the number of copy/ increases needed.


public abstract class BaseLookup<T extends Element> {

private static final int INITIAL_CAPACITY = 500000;
Copy link
Copy Markdown
Member Author

@lqiu96 lqiu96 Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set large initial map capacity to try to reduce the number of copy/ increases needed. This is for ClassLookup, ClassItemsLookup, and PackageLookup. Maybe I can allow configuration of this capacity for the different lookups. ClassLookup (mid size), ClassItemsLookup (large), PackageLookup (small)


public class ElementUtil {

private static final int INITIAL_CAPACITY = 1000000;
Copy link
Copy Markdown
Member Author

@lqiu96 lqiu96 Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set large initial map capacity to try to reduce the number of copy/ increases needed. There are a lot of lookups for a javax.lang.Element (Package, Class, Method) so caching each Element can help speed this up.

@lqiu96 lqiu96 requested a review from suztomo July 21, 2022 19:05
Comment on lines +53 to +54
public List<? extends Element> getEnclosedElements(Element element) {
elementMap.computeIfAbsent(element, this::getEnclosedElementsInternal);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My memo: this is the cache.

@suztomo
Copy link
Copy Markdown
Member

suztomo commented Jul 25, 2022

For my future learning, would you enrich this pull request description with your observations that explain why you focused on optimizing getEnclosedElements?

@lqiu96
Copy link
Copy Markdown
Member Author

lqiu96 commented Jul 25, 2022

@suztomo Sure. Changes were initially part this draft PR: #139, which was two parts 1. Add concurrency and 2. Add Element caching. When I created the original PR, I came across a test failure with the concurrency code so I split out the caching part while I debug the other issue.

Both these changes were part of the initial debugging with YourKit profiler. The concurrent code calling getEnclosedElements() would need to be synchronized between the different threads. They were making the same call to element.getEnclosedElements() (https://docs.oracle.com/javase/7/docs/api/javax/lang/model/element/Element.html#getEnclosedElements()) but the result for this function doesn't change. Adding a map/cache to store the already computed values.

@suztomo
Copy link
Copy Markdown
Member

suztomo commented Jul 26, 2022

@lqiu96 Thanks. Would you paste here the screenshot of YourKit profiler showing getEnclosedElements?
(If you didn't take it, then never mind)

@lqiu96
Copy link
Copy Markdown
Member Author

lqiu96 commented Jul 26, 2022

@suztomo I didn't take a screenshot unfortunately.

@lqiu96 lqiu96 marked this pull request as ready for review July 26, 2022 19:52
@lqiu96 lqiu96 requested a review from a team July 26, 2022 19:52
@lqiu96 lqiu96 merged commit 4bff94e into googleapis:main Jul 27, 2022
@lqiu96 lqiu96 deleted the add_element_cache branch July 27, 2022 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants