Skip to content

Commit

Permalink
perf: optimize escapeTagValue for no replacements case
Browse files Browse the repository at this point in the history
  • Loading branch information
iProdigy authored and PhilippHeuer committed Aug 31, 2020
1 parent e2c135b commit c32c1cd
Showing 1 changed file with 24 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,30 @@ public class EscapeUtils {
* @see <a href="https://ircv3.net/specs/extensions/message-tags.html">Offical spec</a>
*/
public static String escapeTagValue(Object value) {
if (value == null) return "";
char[] unescaped = value.toString().toCharArray();
StringBuilder sb = new StringBuilder(unescaped.length);
for (char c : unescaped) {
final String unescapedString;
if (value == null || (unescapedString = value.toString()) == null) return "";

final char[] unescaped = unescapedString.toCharArray();
final int n = unescaped.length;

// Determine the index of the first replacement needed in the string
int firstReplacement = -1;
for (int i = 0; i < n; i++) {
char c = unescaped[i];
if (c == ';' || c == ' ' || c == '\\' || c == '\r' || c == '\n') {
firstReplacement = i;
break;
}
}

// When no replacements are needed, skip allocating the StringBuilder and copying over the chars
if (firstReplacement < 0) return unescapedString;

// Otherwise: replacement(s) are needed
final StringBuilder sb = new StringBuilder(n + 1); // Set capacity to length of string plus one replacement
sb.append(unescaped, 0, firstReplacement); // Copy over the region of the string that requires no replacements
for (int i = firstReplacement; i < n; i++) { // Perform replacements on the rest of the string as needed
char c = unescaped[i];
switch (c) {
case ';':
sb.append("\\:");
Expand Down

0 comments on commit c32c1cd

Please sign in to comment.