[ 
https://issues.apache.org/jira/browse/GROOVY-6360?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17283640#comment-17283640
 ] 

Paul King commented on GROOVY-6360:
-----------------------------------

GROOVY-9637 will cache the toString() when it can, so helps with part of the 
problem. If you look at {{AbstractStringBuilder#append(CharSequence)}} it has 
special handling for String. If it also had an instanceof check for GString 
that called toString(), then toString() would be called once. Then the multiple 
calls to charAt wouldn't be needed (which triggers the extra calls to 
toString() in this scenario). Of course, you wouldn't necessarily expect Java 
to know about a Groovy class. The proposed PR, 
[https://github.com/apache/groovy/pull/1486], avoids reflection calls for 
charAt and trim, which should remove the performance issues discussed for this 
issue. Perhaps getBytes would also be beneficial but no-one has complained 
about that case yet.

The thing to remember with GStrings is that while they seldom do, they can 
represent dynamic content. Hence it is difficult to optimise as far as you can 
with Strings.
 So, for example, in the example below, it would be wrong to cache the GString 
value:
{code:java}
int count = 0
def gs = "${ -> count}"
def sb = new StringBuilder()
sb.append(gs)
count += 1
sb.append(gs)
assert sb.toString() == '01'
{code}

> GString performance is slow with String's method
> ------------------------------------------------
>
>                 Key: GROOVY-6360
>                 URL: https://issues.apache.org/jira/browse/GROOVY-6360
>             Project: Groovy
>          Issue Type: Improvement
>          Components: groovy-jdk
>    Affects Versions: 2.1.7
>            Reporter: Linh Pham
>            Priority: Minor
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> GString implementation of String's method is very expensive. With trim(), it 
> can be 10 times slower than String's counterpart. 
> *Steps to reproduce:*
> A small test program showed GString.trim() is 10 times slower than 
> String.trim().
> {code}
> def a = " content "
> def b = " ${'content'} "
> println "a class: ${a.class}"    //output: class java.lang.String
> println "b class: ${b.class}"    //output: class 
> org.codehaus.groovy.runtime.GStringImpl
> long start = System.currentTimeMillis()
> 10000000.times {
>     a.trim()
> }
> println "String trim completed in ${System.currentTimeMillis() - start} ms."  
> //output *909* ms
> start = System.currentTimeMillis()
> 10000000.times {
>     b.trim()
> }
> println "GString trim completed in ${System.currentTimeMillis() - start} ms." 
>  //output: *9321 *ms
> {code}
> We can get around the problem by calling toString() on GString before 
> invoking methods, BUT it should be supported inside the Groovy runtime.
> More info at this thread: http://markmail.org/thread/4cti6dgb7pmrzqbl



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to