You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Daniel Sun (Jira)" <ji...@apache.org> on 2020/08/01 15:59:00 UTC

[jira] [Updated] (GROOVY-9637) Improve the performance of GString

     [ https://issues.apache.org/jira/browse/GROOVY-9637?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Daniel Sun updated GROOVY-9637:
-------------------------------
    Description: 
{{GString}} will run {{toString()}} whenever its literal string is needed, e.g. methods like {{equals}}, {{hashCode}} are called, but unfortunately its literal string will be re-constructed for each time and the process costs quite a little of time.

So I propose to check whether {{GString}} values are all of immutable type, e.g. primitive types and their boxed type, {{String}}, etc. If yes, use the cached string literal, otherwise re-construct the literal string.

Here is the test script, Groovy 3.0.5 costs about {{8700ms}}, and PR1329 costs about {{290ms}} on my machine. About {{96.7%}} time is reduced.
{code:groovy}
def gstr = makeGString()
long b = System.currentTimeMillis()
for (int i = 0; i < 10000000; i++) {
	gstr.toString()
}
long e = System.currentTimeMillis()
println "${e - b}ms"

//@groovy.transform.CompileStatic
def makeGString() {
    def now = java.time.LocalDateTime.now()
    "integer: ${1}, double: ${1.2d}, string: ${'x'}, class: ${Map.class}, boolean: ${true}, now: ${now}"
}
{code}

  was:
{{GString}} will run {{toString()}} whenever its literal string is needed, e.g. methods like {{equals}}, {{hashCode}} are called, but unfortunately its literal string will be re-constructed for each time and the process costs quite a little of time.

So I propose to check whether {{GString}} values are all of immutable type, e.g. primitive types and their boxed type, {{String}}, etc. If yes, use the cached string literal, otherwise re-construct the literal string.

Here is the test script, Groovy 3.0.4 costs about {{283ms}}, and PR1309 costs about {{173ms}} on my machine. About {{39%}} time is reduced.
{code:groovy}
long b = System.currentTimeMillis()
def gstr = "a${1}b${1.2}c${'x'}d${Map.class}e${true}"
for (int i = 0; i < 100000; i++) {
	gstr.toString()
}
long e = System.currentTimeMillis()
println "${e - b}ms"
{code}


> Improve the performance of GString
> ----------------------------------
>
>                 Key: GROOVY-9637
>                 URL: https://issues.apache.org/jira/browse/GROOVY-9637
>             Project: Groovy
>          Issue Type: Improvement
>            Reporter: Daniel Sun
>            Assignee: Paul King
>            Priority: Major
>              Labels: breaking
>             Fix For: 4.0.0-alpha-1
>
>          Time Spent: 9h 10m
>  Remaining Estimate: 0h
>
> {{GString}} will run {{toString()}} whenever its literal string is needed, e.g. methods like {{equals}}, {{hashCode}} are called, but unfortunately its literal string will be re-constructed for each time and the process costs quite a little of time.
> So I propose to check whether {{GString}} values are all of immutable type, e.g. primitive types and their boxed type, {{String}}, etc. If yes, use the cached string literal, otherwise re-construct the literal string.
> Here is the test script, Groovy 3.0.5 costs about {{8700ms}}, and PR1329 costs about {{290ms}} on my machine. About {{96.7%}} time is reduced.
> {code:groovy}
> def gstr = makeGString()
> long b = System.currentTimeMillis()
> for (int i = 0; i < 10000000; i++) {
> 	gstr.toString()
> }
> long e = System.currentTimeMillis()
> println "${e - b}ms"
> //@groovy.transform.CompileStatic
> def makeGString() {
>     def now = java.time.LocalDateTime.now()
>     "integer: ${1}, double: ${1.2d}, string: ${'x'}, class: ${Map.class}, boolean: ${true}, now: ${now}"
> }
> {code}



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