Does the Pattern.compile template cache?

This is most likely an implementation detail, but for Oracle and IBM JDKs, at least the compiled template is cached, or should we, as application developers, cache the compiled templates ourselves?

+7
source share
4 answers

I do not believe that the results are cached, and there is no evidence of such behavior in the code or documentation . Of course, it would be rather trivial to implement such a cache, but I would be interested to use the case when such caching is useful.

Re. comment below and String.split () , there is another approach in that the code has a clear path for trivial patterns of 1 or 2 char more complex regular expressions. But it is still not cached.

+5
source

As far as I know, if you look at the code (JDK 6), it does not perform caching, but after creating it, the object of the Pattern object can be cached on the application side and divided between several threads. It seems that the standard template assigns it a final static variable:

private static final Pattern p = Pattern.compile(","); 
+7
source

This is not true. If you have performance sensitive areas, you might want to save the template objects as member variables.

Clojure does this more or less automatically if you have a regular expression in a function.

+3
source

I created a CachedPattern class that can cache Template objects. If you run the main method, you will see that the Java Template objects are actually different instances that also consume memory.

 import java.util.HashMap; import java.util.regex.Pattern; import org.eclipse.core.runtime.Assert; public class CachedPattern { public static void main(String[] args){ Pattern p1 = Pattern.compile("abc"); Pattern p2 = Pattern.compile("abc"); Pattern p3 = Pattern.compile("abc"); Pattern p4 = Pattern.compile("abc"); Pattern p5 = Pattern.compile("abc"); Pattern x1 = CachedPattern.compile("abc"); Pattern x2 = CachedPattern.compile("abc"); Pattern x3 = CachedPattern.compile("abc"); Pattern x4 = CachedPattern.compile("abc"); Pattern x5 = CachedPattern.compile("abc"); // are cached objects the same ? YES! Assert.isTrue(x1.equals(x2)); Assert.isTrue(x1.equals(x3)); Assert.isTrue(x1.equals(x4)); Assert.isTrue(x1.equals(x5)); // are non-cached objects the same ? NO! Assert.isTrue(p1.equals(p2)); //AssertionFailedException } private static HashMap<String, Pattern> cached = new HashMap<>(); /** * This value must be unique, to make sure user won't use this inside "regex" variable, * so that objects without flags would be returned * For example if UNIQUE_HASH would be empty: * compile(pattern = "abc1") * VS. * compile(pattern = "abc", flag = 1) * This would give same keys "abc1" and "abc1" */ private static final String UNIQUE_HASH = "(())[] +@ #$%^@ !@ #$%*"; public static Pattern compile(String regex){ if(cached.containsKey(regex)){ return cached.get(regex); } Pattern p = Pattern.compile(regex); cached.put(regex, p); return p; } public static Pattern compile(String regex, int flags){ String uniqueKey = regex + UNIQUE_HASH + flags; if(cached.containsKey(uniqueKey)){ return cached.get(uniqueKey); } Pattern p = Pattern.compile(regex); cached.put(uniqueKey, p); return p; } } 
+3
source

All Articles