question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JTE is slower than regular String.replace approach

See original GitHub issue

Hello, first of all, thanks for the great library.

I made a simple benchmark in order to test JTE performance and seems JTE is much slower than regular String.replace() at least for simple use cases.

Benchmark:

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 5, time = 1)
public class JTETest {

    String primaryColor = "#ffffff";
    String templateTxt;
    CodeResolver codeResolver = new DirectoryCodeResolver(Path.of("xxx/templates"));
    TemplateEngine templateEngine = TemplateEngine.create(codeResolver, ContentType.Plain);


    @Setup
    public void setup() {
        templateTxt = "<!DOCTYPE html>\n"
                + "<html>\n"
                + "<head>\n"
                + "${primaryColor}\n"
                + "</head>\n"
                + "</html>";

    }

    @Benchmark
    public String concat() {
        return "<!DOCTYPE html>\n"
                + "<html>\n"
                + "<head>\n"
                + primaryColor
                + "\n"
                + "</head>\n"
                + "</html>";
    }

    @Benchmark
    public String replace() {
        return templateTxt.replace("${primaryColor}", primaryColor);
    }

    @Benchmark
    public String templateEngine() {
        TemplateOutput output = new StringOutput();
        templateEngine.render("replace_test.jte", primaryColor, output);
        return output.toString();
    }

}

replace_test.jte:

@param String primaryColor

<!DOCTYPE html>
<html>
<head>
${primaryColor}
</head>
</html>

Result:

Benchmark               Mode  Cnt     Score     Error  Units
JTETest.concat          avgt    5    25.720 ±   2.108  ns/op
JTETest.replace         avgt    5    75.095 ±   8.815  ns/op
JTETest.templateEngine  avgt    5  2867.906 ± 183.810  ns/op

For the large template 1kb and many replacements, JTE is still slower ~30%. Is that expected?

In theory, if the template doesn’t have any control flow, it could be compiled to String concat pattern:

“<head>” + primaryColor + “</head>”, where OptimizeStringConcat kicks in. That should make it even faster than regular String.replace pattern. WDYT?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:16 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
casidcommented, Oct 22, 2020

@doom369 will do that then! And I think it’s a good choice if simple String.replace is all that is needed to not add an additional dependency.

Thanks for posting the benchmark and all the insights on String performance 😃

2reactions
doom369commented, Oct 20, 2020

@casid for Java 8 and below it was -XX:+OptimizeStringConcat. Since Java 9 it’s StringConcatFactory. Checkout this JEP - http://openjdk.java.net/jeps/280 it has a lot of interesting info.

I’m wondering if the JIT would be able to inline the virtual methods of the interface.

Inlining is possible, however, the resulting concatenation won’t be optimized, because it should be chaining calls pattern .append("tag").append(param) otherwise JIT doesn’t optimize it. In the case of StringOutput the result will be:

sb.append();
sb.append();

those code patterns are not optimized.

Read more comments on GitHub >

github_iconTop Results From Across the Web

regex - Python: why regular expression is slower than replace ...
Because regular expressions are more than 4.5 times more complex than a fixed string replacement.
Read more >
Why is Java's String#replace() so slow? - CQSE GmbH
Our first idea was to use regular expressions. Instead of iterating over the map and performing one replacement at a time. We created...
Read more >
Micro optimizations in Java. String.replaceAll - Medium
Now it even makes it a bit slower. That's because of the String. replace method implementation, as it already performs String. indexOf search ......
Read more >
Javascript Replace looks great, but can be slow - ServiceNow
I recently came across a performance issue with the Javascript "replace" function. When I switched to using the Java string replace.
Read more >
Are backticks (``) slower than other strings in JavaScript?
I ran some tests using jsperf to find out which string character works the fastest and whether comparing to the empty string is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found