Browse Source

Reduce overhead of char[] creation

There are more locations which could benefit from not using a
toCharArray on a String, but rather use the charAt method from
the String itself. This to prevent an additional copy of the
char[] being created.
pull/26107/head
Marten Deinum 4 years ago committed by Juergen Hoeller
parent
commit
c9b27af64f
  1. 4
      spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java
  2. 8
      spring-core/src/main/java/org/springframework/core/Conventions.java
  3. 3
      spring-web/src/main/java/org/springframework/http/ContentDisposition.java
  4. 3
      spring-web/src/main/java/org/springframework/http/ResponseCookie.java
  5. 6
      spring-web/src/main/java/org/springframework/http/server/DefaultPathContainer.java
  6. 3
      spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java
  7. 3
      spring-web/src/main/java/org/springframework/web/util/UriComponents.java
  8. 7
      spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java
  9. 7
      spring-web/src/main/java/org/springframework/web/util/pattern/SingleCharWildcardedPathElement.java

4
spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java

@ -475,8 +475,8 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
} }
if (Character.isJavaIdentifierStart(candidateToken.charAt(0)) && if (Character.isJavaIdentifierStart(candidateToken.charAt(0)) &&
Character.isLowerCase(candidateToken.charAt(0))) { Character.isLowerCase(candidateToken.charAt(0))) {
char[] tokenChars = candidateToken.toCharArray(); for (int i = 1; i < candidateToken.length(); i++) {
for (char tokenChar : tokenChars) { char tokenChar = candidateToken.charAt(i);
if (!Character.isJavaIdentifierPart(tokenChar)) { if (!Character.isJavaIdentifierPart(tokenChar)) {
return null; return null;
} }

8
spring-core/src/main/java/org/springframework/core/Conventions.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -225,11 +225,11 @@ public final class Conventions {
if (!attributeName.contains("-")) { if (!attributeName.contains("-")) {
return attributeName; return attributeName;
} }
char[] chars = attributeName.toCharArray(); char[] result = new char[attributeName.length() -1]; // not completely accurate but good guess
char[] result = new char[chars.length -1]; // not completely accurate but good guess
int currPos = 0; int currPos = 0;
boolean upperCaseNext = false; boolean upperCaseNext = false;
for (char c : chars) { for (int i = 0; i < attributeName.length(); i++ ) {
char c = attributeName.charAt(i);
if (c == '-') { if (c == '-') {
upperCaseNext = true; upperCaseNext = true;
} }

3
spring-web/src/main/java/org/springframework/http/ContentDisposition.java

@ -485,7 +485,8 @@ public final class ContentDisposition {
} }
boolean escaped = false; boolean escaped = false;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (char c : filename.toCharArray()) { for (int i = 0; i < filename.length() ; i++) {
char c = filename.charAt(i);
if (!escaped && c == '"') { if (!escaped && c == '"') {
sb.append("\\\""); sb.append("\\\"");
} }

3
spring-web/src/main/java/org/springframework/http/ResponseCookie.java

@ -386,9 +386,8 @@ public final class ResponseCookie extends HttpCookie {
start = 1; start = 1;
end--; end--;
} }
char[] chars = value.toCharArray();
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
char c = chars[i]; char c = value.charAt(i);
if (c < 0x21 || c == 0x22 || c == 0x2c || c == 0x3b || c == 0x5c || c == 0x7f) { if (c < 0x21 || c == 0x22 || c == 0x2c || c == 0x3b || c == 0x5c || c == 0x7f) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"RFC2616 cookie value cannot have '" + c + "'"); "RFC2616 cookie value cannot have '" + c + "'");

6
spring-web/src/main/java/org/springframework/http/server/DefaultPathContainer.java

@ -232,8 +232,6 @@ final class DefaultPathContainer implements PathContainer {
private final String valueToMatch; private final String valueToMatch;
private final char[] valueToMatchAsChars;
private final MultiValueMap<String, String> parameters; private final MultiValueMap<String, String> parameters;
@ -243,7 +241,6 @@ final class DefaultPathContainer implements PathContainer {
DefaultPathSegment(String value, String valueToMatch, MultiValueMap<String, String> params) { DefaultPathSegment(String value, String valueToMatch, MultiValueMap<String, String> params) {
this.value = value; this.value = value;
this.valueToMatch = valueToMatch; this.valueToMatch = valueToMatch;
this.valueToMatchAsChars = valueToMatch.toCharArray();
this.parameters = CollectionUtils.unmodifiableMultiValueMap(params); this.parameters = CollectionUtils.unmodifiableMultiValueMap(params);
} }
@ -254,7 +251,6 @@ final class DefaultPathContainer implements PathContainer {
this.value = value; this.value = value;
this.valueToMatch = value.contains(separator.encodedSequence()) ? this.valueToMatch = value.contains(separator.encodedSequence()) ?
value.replaceAll(separator.encodedSequence(), separator.value()) : value; value.replaceAll(separator.encodedSequence(), separator.value()) : value;
this.valueToMatchAsChars = this.valueToMatch.toCharArray();
this.parameters = EMPTY_PARAMS; this.parameters = EMPTY_PARAMS;
} }
@ -271,7 +267,7 @@ final class DefaultPathContainer implements PathContainer {
@Override @Override
public char[] valueToMatchAsChars() { public char[] valueToMatchAsChars() {
return this.valueToMatchAsChars; return this.valueToMatch.toCharArray();
} }
@Override @Override

3
spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java

@ -791,7 +791,8 @@ final class HierarchicalUriComponents extends UriComponents {
clear(this.currentLiteral); clear(this.currentLiteral);
clear(this.currentVariable); clear(this.currentVariable);
clear(this.output); clear(this.output);
for (char c : source.toCharArray()) { for (int i = 0; i < source.length(); i++) {
char c = source.charAt(i);
if (c == '{') { if (c == '{') {
level++; level++;
if (level == 1) { if (level == 1) {

3
spring-web/src/main/java/org/springframework/web/util/UriComponents.java

@ -278,7 +278,8 @@ public abstract class UriComponents implements Serializable {
int level = 0; int level = 0;
int lastCharIndex = 0; int lastCharIndex = 0;
char[] chars = new char[source.length()]; char[] chars = new char[source.length()];
for (char c : source.toCharArray()) { for (int i = 0; i < source.length(); i++) {
char c = source.charAt(i);
if (c == '{') { if (c == '{') {
level++; level++;
} }

7
spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -69,10 +69,9 @@ class LiteralPathElement extends PathElement {
return false; return false;
} }
char[] data = ((PathContainer.PathSegment)element).valueToMatchAsChars();
if (this.caseSensitive) { if (this.caseSensitive) {
for (int i = 0; i < this.len; i++) { for (int i = 0; i < this.len; i++) {
if (data[i] != this.text[i]) { if (value.charAt(i) != this.text[i]) {
return false; return false;
} }
} }
@ -80,7 +79,7 @@ class LiteralPathElement extends PathElement {
else { else {
for (int i = 0; i < this.len; i++) { for (int i = 0; i < this.len; i++) {
// TODO revisit performance if doing a lot of case insensitive matching // TODO revisit performance if doing a lot of case insensitive matching
if (Character.toLowerCase(data[i]) != this.text[i]) { if (Character.toLowerCase(value.charAt(i)) != this.text[i]) {
return false; return false;
} }
} }

7
spring-web/src/main/java/org/springframework/web/util/pattern/SingleCharWildcardedPathElement.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -74,11 +74,10 @@ class SingleCharWildcardedPathElement extends PathElement {
return false; return false;
} }
char[] data = ((PathSegment)element).valueToMatchAsChars();
if (this.caseSensitive) { if (this.caseSensitive) {
for (int i = 0; i < this.len; i++) { for (int i = 0; i < this.len; i++) {
char ch = this.text[i]; char ch = this.text[i];
if ((ch != '?') && (ch != data[i])) { if ((ch != '?') && (ch != value.charAt((i)))) {
return false; return false;
} }
} }
@ -87,7 +86,7 @@ class SingleCharWildcardedPathElement extends PathElement {
for (int i = 0; i < this.len; i++) { for (int i = 0; i < this.len; i++) {
char ch = this.text[i]; char ch = this.text[i];
// TODO revisit performance if doing a lot of case insensitive matching // TODO revisit performance if doing a lot of case insensitive matching
if ((ch != '?') && (ch != Character.toLowerCase(data[i]))) { if ((ch != '?') && (ch != Character.toLowerCase(value.charAt(i)))) {
return false; return false;
} }
} }

Loading…
Cancel
Save