Skip to content

Performance improvements in TemplateVariable.essence() #1764

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

Performance improvements in TemplateVariable.essence() #1764

wants to merge 1 commit into from

Conversation

MikeRocke
Copy link
Contributor

Noticed this took a relatively large portion of time when Unit tests of LinkBuilding (via Integration testing and Testing Controller layer), due to String format needing to parse the format string for each template variable

Minor spell corrections on test methods when spotted

Noticed this took a relatively large portion of time when Unit tests of LinkBuilding (via Integration testing and Testing Controller layer), due to String format needing to parse the format string for each template variable
@odrotbohm
Copy link
Member

Nice one! Do you have any numbers hand pre and post optimization?

@MikeRocke
Copy link
Contributor Author

Hey there!

Most welcome

I have some rough numbers from last night.

First rough exercise, just to loop through many times for same input,

        String name = "make";
        int limit = 2;
        TemplateVariable.Cardinality cardinality = TemplateVariable.Cardinality.COMPOSITE;
        boolean composite = cardinality.equals(TemplateVariable.Cardinality.COMPOSITE);

        //510ms
        for (int i = 0; i < 100000; i++) {
            String originalValue = String.format("%s%s%s", name, limit != -1 ? ":".concat(String.valueOf(limit)) : "", composite ? "*" : "");
        }

and

        String name = "make";
        int limit = 2;
        TemplateVariable.Cardinality cardinality = TemplateVariable.Cardinality.COMPOSITE;
        boolean composite = cardinality.equals(TemplateVariable.Cardinality.COMPOSITE);

        //25ms
        for (int i = 0; i < 100000; i++) {
            StringBuilder stringBuilder = new StringBuilder(name);
            if (limit != -1) {
                stringBuilder = stringBuilder.append(":").append(String.valueOf(limit));
            }
            if (composite) {
                stringBuilder = stringBuilder.append("*");
            }
            String newvalue = stringBuilder.toString();
        }

Approx ~500ms before, and ~25ms afterwards

Unfortunately, don't have the evidence to hand on the next exercise, but I seen a ~33% improvement on my build duration, as they tend to perform requests to RestControllers with unique data for each test

And spotted this cause with async profiler in intellij, that the essence method was a big contributor
Screenshot 2022-04-14 at 13 27 12

Appreciate these aren't the most scientific methods, and am happy to get some more conclusive before and afters

@odrotbohm
Copy link
Member

Thanks. I took a few extra steps to remove all usage of String.format(…) in that path, added a quick benchmark calling ….toString() and got from this:

Benchmark                                    Mode  Cnt         Score        Error  Units
TemplateVariableBenchmark.toString(…)       thrpt    3   2803239,270 ± 110258,955  ops/s

to this:

Benchmark                                    Mode  Cnt         Score        Error  Units
TemplateVariableBenchmark.toString(…)       thrpt    3  10753653,459 ± 156684,459  ops/s

which is almost a 4x improvement. Pushes coming in a minute.

@odrotbohm odrotbohm changed the title Optimization on essence function. Performance improvements in TemplateVariable.essence() Apr 14, 2022
@odrotbohm odrotbohm self-assigned this Apr 14, 2022
@odrotbohm odrotbohm added type: enhancement in: core Core parts of the project labels Apr 14, 2022
@odrotbohm odrotbohm added this to the 2.0 M3 milestone Apr 14, 2022
@MikeRocke
Copy link
Contributor Author

Fantastic! Thank you!

odrotbohm added a commit that referenced this pull request Apr 14, 2022
Heavily inspired by the PR @MikeRocke, we removed all usage of String.format(…) from hot code paths triggered by ….toString() as it's used in general output a lot.

Before:

Benchmark                                    Mode  Cnt         Score        Error  Units
TemplateVariableBenchmark.toString(…)       thrpt    3   2803239,270 ± 110258,955  ops/s

After:

Benchmark                                    Mode  Cnt         Score        Error  Units
TemplateVariableBenchmark.toString(…)       thrpt    3  10753653,459 ± 156684,459  ops/s
@odrotbohm
Copy link
Member

Backported until 1.4.x. Feel free to give the snapshots a try.

@odrotbohm odrotbohm closed this Apr 14, 2022
@MikeRocke
Copy link
Contributor Author

Just an update, quick experiment of v1.4.1 against 1.4.2-SNAPSHOT in one of our app build, test phase went from 800s to 534s. I know I should repeat the experiments to get a good statistical figure but overall, looks like a win! Super thank you @odrotbohm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Core parts of the project type: enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants