Improve the performance of replacing strings

(cherry picked from commit 099fbbc)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/e9fb7840
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/e9fb7840
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/e9fb7840

Branch: refs/heads/GROOVY_2_6_X
Commit: e9fb784062ab7b4e8f20519312ac855b184d8e25
Parents: cff0df4
Author: sunlan <sun...@apache.org>
Authored: Wed Aug 30 02:05:18 2017 +0800
Committer: sunlan <sun...@apache.org>
Committed: Wed Aug 30 02:15:06 2017 +0800

----------------------------------------------------------------------
 src/main/antlr/GroovyParser.g4                  |  4 +-
 .../groovy/parser/antlr4/util/StringUtils.java  | 42 ++++++++++++++++----
 2 files changed, 36 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/e9fb7840/src/main/antlr/GroovyParser.g4
----------------------------------------------------------------------
diff --git a/src/main/antlr/GroovyParser.g4 b/src/main/antlr/GroovyParser.g4
index 861160b..d806baa 100644
--- a/src/main/antlr/GroovyParser.g4
+++ b/src/main/antlr/GroovyParser.g4
@@ -1283,7 +1283,7 @@ keywords
 rparen
     :   RPAREN
     |
-        // !!!Error Alternative
+        // !!!Error Alternative, impact the performance of parsing
         ~LPAREN
         { require(false, "Missing ')'", -1); }
     ;
@@ -1291,7 +1291,7 @@ rparen
 rbrack
     :   RBRACK
     |
-        // !!!Error Alternative
+        // !!!Error Alternative, impact the performance of parsing
         ~LBRACK
         { require(false, "Missing ']'", -1); }
     ;

http://git-wip-us.apache.org/repos/asf/groovy/blob/e9fb7840/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/util/StringUtils.java
----------------------------------------------------------------------
diff --git 
a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/util/StringUtils.java
 
b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/util/StringUtils.java
index 5aad139..4c58256 100644
--- 
a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/util/StringUtils.java
+++ 
b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/util/StringUtils.java
@@ -80,7 +80,7 @@ public class StringUtils {
                                                        }
                                                });
 
-               return result.replace("\\\\", "\\");
+               return replace(result, Maps.of("\\\\", "\\"));
     }
 
        public static final int NONE_SLASHY = 0;
@@ -92,15 +92,17 @@ public class StringUtils {
                        text = StringUtils.replaceHexEscapes(text);
                        text = StringUtils.replaceLineEscape(text);
 
+                       StringBuilder sb = new StringBuilder(text);
                        if (slashyType == SLASHY) {
-                               text = text.replace("\\/", "/");
+                               replace(sb, Maps.of("\\/", "/"));
                        }
 
                        if (slashyType == DOLLAR_SLASHY) {
-                               text = text.replace("$$", "$");
-                               text = text.replace("$/", "/");
+                               replace(sb, Maps.of("$$", "$"));
+                               replace(sb, Maps.of("$/", "/"));
                        }
 
+                       text = sb.toString();
                } else if (slashyType == NONE_SLASHY) {
                        text = StringUtils.replaceEscapes(text);
                } else {
@@ -111,8 +113,7 @@ public class StringUtils {
        }
 
        private static String replaceEscapes(String text) {
-               text = text.replace("\\$", "$");
-
+               text = replace(text, Maps.of("\\$", "$"));
                text = StringUtils.replaceLineEscape(text);
 
         return 
StringUtils.replaceStandardEscapes(replaceHexEscapes(replaceOctalEscapes(text)));
@@ -138,7 +139,7 @@ public class StringUtils {
        }
 
        public static String removeCR(String text) {
-        return text.replace("\r\n", "\n");
+               return replace(text, Maps.of("\r\n", "\n"));
     }
 
        public static long countChar(String text, char c) {
@@ -150,9 +151,34 @@ public class StringUtils {
                return count; // return text.chars().filter(e -> c == 
e).count();
        }
 
+       public static String replace(String str, Map<String, String> 
replacements) {
+               return replace(new StringBuilder(str), replacements).toString();
+       }
+
+       public static StringBuilder replace(StringBuilder sb, Map<String, 
String> replacements) {
+
+               for (Map.Entry<String, String> entry : replacements.entrySet()) 
{
+                       String key = entry.getKey();
+                       int keyLength = key.length();
+
+                       String value = entry.getValue();
+                       int valueLength = value.length();
+
+                       int start = sb.indexOf(key, 0);
+                       while (start > -1) {
+                               int end = start + keyLength;
+                               int nextSearchStart = start + valueLength;
+                               sb.replace(start, end, value);
+                               start = sb.indexOf(key, nextSearchStart);
+                       }
+               }
+
+               return sb;
+       }
+
        public static String trimQuotations(String text, int quotationLength) {
                int length = text.length();
 
-               return length == quotationLength * 2 ? "" : 
text.substring(quotationLength, length - quotationLength);
+               return length == quotationLength << 1 ? "" : 
text.substring(quotationLength, length - quotationLength);
        }
 }
\ No newline at end of file

Reply via email to