The HttpHeaders.getAcceptLanguageAsLocales was incurring overhead from using a Stream, as well as calling the fairly expensive Locale.getDisplayName method.

Switch to using an ArrayList, and skipping over wildcard ranges to avoid needing to check the display name.

Here is a CPU flamegraph from one of our apps where this method call stands out.

Spring Optimize HttpHeaders.getAcceptLanguageAsLocales

Comment From: jhoeller

@poutsma the present check there seems worth optimizing in the 6.1.x line. getDisplayName being a specific culprit in that method, but also .stream() usage worth reviewing in other HttpHeaders methods.

I'm not sure about the intent of the original getDisplayName check there and whether the range check replacement is 100% equivalent for our purposes, so I'll leave it up to you to refine this if necessary.

Comment From: kilink

I'm fairly certain checking of display name was to handle wildcards as described in rfc4647. Based on the validation in Locale.LanguageRange.parse, it appeared to me to be the only possible way to end up with a Locale instance without a display name, as all other invalid language tags are rejected.

Locale.forLanguageTag("*").getDisplayName(); // empty
Locale.forLanguageTag("*-CA").getDisplayName(); // empty

Comment From: poutsma

Merged. Thanks for submitting a PR, @kilink !