Optimize MediaType parsing
Prior to this commit, `MediaType.parseMediaType` would already rely on the internal LRU cache in `MimeTypeUtils` for better performance. With that optimization, the parsing of raw media types is skipped for cached elements. But still, `MediaType.parseMediaType` would first get a cached `MimeType` instance from that cache and then instantiate a `new MediaType(type, subtype, parameters)`. This constructor not only replays the `MimeType` checks on type/subtyme tokens and parameters, but it also performs `MediaType`-specific checks on parameters. Such checks are not required, as we're using an existing `MimeType` instance in the first place. This commit adds a new protected copy constructor (skipping checks) in `MimeType` and uses it in `MediaType.parseMediaType` as a result. This yields interesting performance improvements, with +400% throughput and -40% allocation/call in benchmarks. This commit also introduces a new JMH benchmark for future optimization work. Closes gh-24769
This commit is contained in:
@@ -190,6 +190,18 @@ public class MimeType implements Comparable<MimeType>, Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy-constructor that copies the type, subtype and parameters of the given {@code MimeType},
|
||||
* skipping checks performed in other constructors.
|
||||
* @param other the other MimeType
|
||||
*/
|
||||
protected MimeType(MimeType other) {
|
||||
this.type = other.type;
|
||||
this.subtype = other.subtype;
|
||||
this.parameters = other.parameters;
|
||||
this.toStringValue = other.toStringValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given token string for illegal characters, as defined in RFC 2616,
|
||||
* section 2.2.
|
||||
@@ -197,7 +209,7 @@ public class MimeType implements Comparable<MimeType>, Serializable {
|
||||
* @see <a href="https://tools.ietf.org/html/rfc2616#section-2.2">HTTP 1.1, section 2.2</a>
|
||||
*/
|
||||
private void checkToken(String token) {
|
||||
for (int i = 0; i < token.length(); i++ ) {
|
||||
for (int i = 0; i < token.length(); i++) {
|
||||
char ch = token.charAt(i);
|
||||
if (!TOKEN.get(ch)) {
|
||||
throw new IllegalArgumentException("Invalid token character '" + ch + "' in token \"" + token + "\"");
|
||||
|
||||
Reference in New Issue
Block a user