Skip to content
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

String.replaceAll and String.replaceFirst are known to be slow due to Pattern compiles. Prefer Pattern.matches().replaceAll() #1633

Closed
kad-vetteh opened this issue Jan 18, 2024 · 2 comments · Fixed by #1691
Labels
core deegree core modules enhancement enhancement or improvement
Milestone

Comments

@kad-vetteh
Copy link
Contributor

String method 'replaceAll' is implemented as:

 public String replaceAll(String regex, String replacement) {
    return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}

String method 'replaceFirst' is implemented as:

public String replaceFirst(String regex, String replacement) {
     return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
}

These methods provide a convenience method for creating a Pattern using Pattern.compile(), The Pattern.compile() method is slow, and should be avoided. The best way to do this is to statically compile the Pattern, and use the matcher from the static compiled pattern. This could improve performance a lot when the String.replaceAll method or String.replaceFirst method is called in the wrong place. (i.e. in a for loop). The pattern will be compiled on every invocation of the replaceAll or replaceFirst method.

Find and replace the method replaceAll and replaceFirst and change them into static compiled Patterns.

replaceAll Before (slow)

public void method(String str)  {
     String output = str.replaceAll("regex", "replacement");
}  

replaceAll After (improved performance)

private final static Pattern PATTERN_NAME = Pattern.compile("regex");

public void method(String str)  {
     String output = PATTERN_NAME.matches(str).replaceAll("replacement");
}  

replaceFirst Before (slow)

public void method(String str)  {
     String output = str.replaceFirst("regex", "replacement");
}  

replaceFirst After (improved performance)

private final static Pattern PATTERN_NAME = Pattern.compile("regex");

public void method(String str)  {
     String output = PATTERN_NAME.matches(str).replaceFirst("replacement");
}  
@tfr42
Copy link
Member

tfr42 commented Jan 24, 2024

@kad-vetteh Thanks for the proposal. Can you tell us a little more about the context when this will effect deegree at runtime? And of course any source code and runtime improvement is welcome. So, we will be happy, if you are preparing a pull request.

@kad-vetteh
Copy link
Contributor Author

@tfr42 I have attached a draft pull request: #1639
I was looking in the code recently, and noticed the methods, feel free to try if it makes some difference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core deegree core modules enhancement enhancement or improvement
Projects
None yet
2 participants