private static final Pattern URL_LIKE = Pattern.compile("^https?://");
// …
private String getPhotoLink(Long clientId) {
return Optional.of(clientId)
.map(photoRepository::findLastByClientId)
.map(Photo::getLink)
.map(link -> URL_LIKE.matcher(link).matches()
? link
: String.format(photoUrlPattern, link))
.orElse(null);
}
public class TestRegexVsStringUtils {
private static final String TEST_STRING = "https://some.example.com/api/images/9876543210";
private static final Pattern PATTERN = Pattern.compile("^https?://");
private static final String HTTP = "http://";
private static final String HTTPS = "https://";
public static void main(String[] args) {
long t0 = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
PATTERN.matcher(TEST_STRING).matches();
}
long t1 = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
StringUtils.startsWithAny(TEST_STRING, HTTP, HTTPS);
}
long t2 = System.currentTimeMillis();
System.out.println("Pattern: " + (t1 - t0) + " ms.");
System.out.println("Apache: " + (t2 - t1) + " ms.");
}
}
private static final String TEST_STRING = "https://some.example.com/api/images/9876543210";
private static final Pattern PATTERN = Pattern.compile("^https?://");
private static final String HTTP = "http://";
private static final String HTTPS = "https://";
private static final int SIZE = 1000;
public static void main(String[] args) {
boolean[] result = new boolean[SIZE];
long t1 = System.currentTimeMillis();
for (int i = 0; i < SIZE; i++) {
result[i] = PATTERN.matcher(TEST_STRING).matches();
}
t1 = System.currentTimeMillis() - t1;
for (boolean b : result) {
if (!b) { throw new RuntimeException("pattern wrong."); }
}
long t2 = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
StringUtils.startsWithAny(TEST_STRING, HTTP, HTTPS);
}
t2 = System.currentTimeMillis() - t2;
for (boolean b : result) {
if (!b) { throw new RuntimeException("apache wrong."); }
}
System.out.println("Pattern: " + t1 + " ms.");
System.out.println("Apache: " + t2 + " ms.");
}
}
public static void main(String[] args) {
boolean[] result = new boolean[SIZE];
long t1 = System.currentTimeMillis();
for (int i = 0; i < SIZE; i++) {
result[i] = PATTERN.matcher(TEST_STRING).find();
}
t1 = System.currentTimeMillis() - t1;
for (boolean b : result) {
if (!b) { throw new RuntimeException("pattern wrong."); }
}
long t2 = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
StringUtils.startsWithAny(TEST_STRING, HTTP, HTTPS);
}
t2 = System.currentTimeMillis() - t2;
for (boolean b : result) {
if (!b) { throw new RuntimeException("apache wrong."); }
}
System.out.println("Pattern: " + t1 + " ms.");
System.out.println("Apache: " + t2 + " ms.");
}
Pattern: 6 ms.
Apache: 8 ms.
mvn archetype:generate
-DinteractiveMode=false
-DarchetypeGroupId=org.openjdk.jmh
-DarchetypeArtifactId=jmh-java-benchmark-archetype
-DgroupId=ru.rcktsci.experiments
-DartifactId=pattern-vs-apache-benchmark
-Dversion=1.0
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
@Warmup(iterations = 1, time = 10)
@Measurement(iterations = 1, time = 10)
@Fork(value = 1)
public class MyBenchmark {
private static final String TEST_STRING = "https://some.example.com/api/images/9876543210";
private static final Pattern PATTERN = Pattern.compile("^https?://");
private static final String HTTP = "http://";
private static final String HTTPS = "https://";
@Benchmark
public boolean testPattern() {
return PATTERN.matcher(TEST_STRING).find();
}
@Benchmark
public boolean testApache() {
return StringUtils.startsWithAny(TEST_STRING, HTTP, HTTPS);
}
@Benchmark
public boolean testManual() {
return TEST_STRING.startsWith(HTTP)
|| TEST_STRING.startsWith(HTTPS);
}
}
Benchmark Mode Cnt Score Error Units
MyBenchmark.testApache thrpt 32386558,554 ops/s
MyBenchmark.testManual thrpt 378162645,117 ops/s
MyBenchmark.testPattern thrpt 12985366,516 ops/s