You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by jw...@apache.org on 2016/06/25 05:25:08 UTC

groovy git commit: GROOVY-7873 - Regression performance issue in string methods (closes #356)

Repository: groovy
Updated Branches:
  refs/heads/master d1308e20b -> 9d94e2e4f


GROOVY-7873 - Regression performance issue in string methods (closes #356)

In order to implement CharSequence the GString implementation must call toString each time a CharSequence method is invoked.  This is expensive, so GStrings should be converted toString if methods such as charAt are going to be called from a loop.


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

Branch: refs/heads/master
Commit: 9d94e2e4f5b8ec84296ac3d92851807df933b2d7
Parents: d1308e2
Author: John Wagenleitner <jw...@apache.org>
Authored: Fri Jun 24 22:21:06 2016 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Fri Jun 24 22:22:12 2016 -0700

----------------------------------------------------------------------
 .../org/codehaus/groovy/runtime/StringGroovyMethods.java | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/9d94e2e4/src/main/org/codehaus/groovy/runtime/StringGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/StringGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/StringGroovyMethods.java
index 2c8f794..0817dd2 100644
--- a/src/main/org/codehaus/groovy/runtime/StringGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/StringGroovyMethods.java
@@ -434,15 +434,18 @@ public class StringGroovyMethods extends DefaultGroovyMethodsSupport {
 
         int i = 0;
 
+        // GROOVY-7873: GString calls toString() on each invocation of CharSequence methods such
+        // as charAt which is very expensive for large GStrings.
+        CharSequence cs = (self instanceof GString) ? self.toString() : self;
         while (i < len) {
-            final char ch = self.charAt(i++);
+            final char ch = cs.charAt(i++);
 
             switch (ch) {
                 case '\r':
                     sb.append(lineSeparator);
 
                     // Eat the following LF if any.
-                    if ((i < len) && (self.charAt(i) == '\n')) {
+                    if ((i < len) && (cs.charAt(i) == '\n')) {
                         ++i;
                     }
 
@@ -601,7 +604,9 @@ public class StringGroovyMethods extends DefaultGroovyMethodsSupport {
         private final CharSequence delegate;
 
         public LineIterable(CharSequence cs) {
-            this.delegate = cs;
+            // GROOVY-7873: GString calls toString() on each invocation of CharSequence methods such
+            // as charAt which is very expensive for large GStrings.
+            this.delegate = (cs instanceof GString) ? cs.toString() : cs;
         }
 
         @Override