Skip to content

Compilation horrible slow on some huge statements #18398

@uschindler

Description

@uschindler

While working on indify string concats for painless, I noticed that some statements take veeery long to compile. Some background:

Indy string concats only allow a maximum of 200 parts per invokedynamic. To test the code to allow more (using intermediate results), I added a simple statement with 211 items and let painless parse it:

String s = "cat"; return s + "000".toString() + "001".toString() + ... + "209".toString();

This takes on painless on my computer up to 300 seconds. If I remove the .toString() calls, it gets a bit faster, but the result is that strings are already merged while compiling (so the .toString() is just a workaround to prevent concats on compilation: I did not find a test for that, its cool that painless does this!). It gets even slower if you instead cast every single string to (def), its still works and works and works since 1000s.

Looks like there is some exponential runtime problem.

This is my test code:

    public void testAppendMany() {
        StringBuilder script = new StringBuilder("String s = \"cat\"; return s");
        StringBuilder result = new StringBuilder("cat");
        for (int i = 0; i < WriterConstants.MAX_INDY_STRING_CONCAT_ARGS + 10; i++) {
            final String s = String.format(Locale.ROOT,  "%03d", i);
            script.append(" + '").append(s).append("'.toString()");
            result.append(s);
        }
        System.out.println(Debugger.toString(script.toString()));
        //assertEquals(result.toString(), exec(script.toString()));
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions