[
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)