Hey team !

We have an interesting issue where our propertySource use can be CPU taxing on our systems due to 1/ many propertySources setup (sometimes 80+), 2/ many properties setup over those propertySources (sometimes 1000+).

It seems like the reason is the support for relaxed binding and use of ConfigurationPropertySourcesPropertySource in the first position of the list of propertySources although it can be reproduced when "forced" in last position as well. The property resolution is doing a breadth first search of all possible bindings in this layer then it's doing an exact match again a second time. Our flamegraph have revealed a lot of String manipulations happening in hot paths where we use environment.getProperty.

In our use cases we use environment.getProperty sometimes more than once per request since some properties could have changed. One use case for instance is a dynamic timeout. I imagine any use case with a MutablePropertySource used in a request or messaging path would reproduce that problem.

We are envisioning caching as a possible solution: - a new first position property source acting as a cache - caching hit and misses and if a mutable source is present, syncing any refresh with this cache - optionally providing metrics to that cache to analyse property resolutions patterns

The cache could be lazily built or partially (maybe fully?) hydrated on startup if desired although this should be an opt-in given the impact it could have on startup time.

Comment From: philwebb

@smaldini Are you able to put together something that replicates the issue? It would be really helpful if we could reproduce this locally so that we can assess the impact of any cache changes we make.

Comment From: philwebb

Also, is it possible to share the flame graph.

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.

Comment From: mbhave

One thing I realized is that we might be doing a double lookup for missing properties. I don't think this is related to the slowness but I was wondering if there is something we can do avoid that. The ConfigurationPropertySourcesPropertySource wraps all other property sources in the environment. Since it's just another PropertySource, if the property is not found in that source, environment.getProperty will continue looking for it in the other property sources. These property sources have already been searched for because they are wrapped by ConfigurationPropertySourcesPropertySource.

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: smaldini

Sorry i didn't look at those notifications - apologies @philwebb @mbhave ! I can't easily provide the flamegraph that showed this but I can try to do a repro case, also the test would be very simple, just a JMH over environment .getProperty with a missed property, vs a property in various locations (first and last).

@mbhave suggestion looks good, if we miss in the ConfigurationPropertySourcesPropertySource we shouldn't go further.

Comment From: philwebb

See also #17400