Skip to content

Commit 184ee6c

Browse files
committed
Avoid using Pattern and Streams in UnionPath init
Speeds up creation of UnionPath significantly. Reduces time spend in testJarFileExists from 7585 to 2777, other tests like testCommonPathUtilities see improvements as well
1 parent 36a991f commit 184ee6c

2 files changed

Lines changed: 30 additions & 23 deletions

File tree

src/main/java/cpw/mods/niofs/union/UnionPath.java

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,16 @@
99
import java.nio.file.WatchKey;
1010
import java.nio.file.WatchService;
1111
import java.util.ArrayDeque;
12+
import java.util.ArrayList;
1213
import java.util.Arrays;
1314
import java.util.Deque;
15+
import java.util.List;
1416
import java.util.Objects;
17+
import java.util.StringJoiner;
1518
import java.util.function.IntBinaryOperator;
16-
import java.util.regex.Pattern;
17-
import java.util.stream.Collectors;
1819
import java.util.stream.IntStream;
1920

2021
public class UnionPath implements Path {
21-
private static final Pattern SEPARATOR_BEGIN_END;
22-
private static final Pattern SEPARATOR_DUPLICATES;
23-
24-
private static final Pattern SEPARATOR_SPLIT;
25-
26-
static {
27-
var sep = "(?:"+ Pattern.quote(UnionFileSystem.SEP_STRING) + ")";
28-
SEPARATOR_BEGIN_END = Pattern.compile("^" + sep + "*|" + sep + "*$");
29-
SEPARATOR_DUPLICATES = Pattern.compile(sep + "(?=" + sep + ")");
30-
SEPARATOR_SPLIT = Pattern.compile(sep);
31-
}
3222
private final UnionFileSystem fileSystem;
3323
private final boolean absolute;
3424
private final String[] pathParts;
@@ -42,9 +32,13 @@ public class UnionPath implements Path {
4232
this.absolute = false;
4333
this.pathParts = new String[0];
4434
} else {
45-
final var longstring = Arrays.stream(pathParts)
46-
.filter(part -> !part.isEmpty())
47-
.collect(Collectors.joining(UnionFileSystem.SEP_STRING));
35+
StringJoiner joiner = new StringJoiner(UnionFileSystem.SEP_STRING);
36+
for (String element : pathParts) {
37+
if (!element.isEmpty()) {
38+
joiner.add(element);
39+
}
40+
}
41+
final var longstring = joiner.toString();
4842
this.absolute = longstring.startsWith(UnionFileSystem.SEP_STRING);
4943
this.pathParts = getPathParts(longstring);
5044
}
@@ -67,13 +61,22 @@ private UnionPath(final UnionFileSystem fileSystem, boolean absolute, boolean is
6761
}
6862

6963
private String[] getPathParts(final String longstring) {
70-
var clean = longstring.replace("\\", UnionFileSystem.SEP_STRING);
71-
clean = SEPARATOR_BEGIN_END.matcher(clean).replaceAll("");
72-
clean = SEPARATOR_DUPLICATES.matcher(clean).replaceAll("");
73-
if (clean.isEmpty())
74-
return new String[0];
75-
else
76-
return SEPARATOR_SPLIT.split(clean);
64+
var clean = longstring.replace('\\', '/');
65+
int startIndex = 0;
66+
List<String> parts = new ArrayList<>();
67+
while (startIndex != longstring.length()) {
68+
int index = clean.indexOf('/', startIndex);
69+
if (index == -1) {
70+
parts.add(clean.substring(startIndex));
71+
break;
72+
}
73+
// Skips double slash and slash and start/end
74+
if (index != startIndex) {
75+
parts.add(clean.substring(startIndex, index));
76+
}
77+
startIndex = (index + 1);
78+
}
79+
return parts.toArray(String[]::new);
7780
}
7881

7982
@Override

src/test/java/cpw/mods/niofs/union/TestUnionPath.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ void testUnionPath() {
4040
var abs123 = fs.getPath("/one/two/three");
4141
var abs1223 = fs.getPath("/one/two/./three");
4242
var abs12up3 = fs.getPath("/one/two/../three");
43+
var abs12up3otherslash = fs.getPath("/one/two/..\\three");
4344
var abs13 = fs.getPath("/one/three");
4445
var abs13slash = fs.getPath("/one/three/");
4546
var abs1slash3 = fs.getPath("/one//three");
47+
var abs1otherslash3 = fs.getPath("/one\\/three");
4648
var absUpUp1 = fs.getPath("/../../one");
4749
var absUpUp123 = fs.getPath("/../../one/two/three");
4850

@@ -51,6 +53,8 @@ void testUnionPath() {
5153
assertEquals(rel13, rel1slash3);
5254
assertEquals(abs13, abs13slash);
5355
assertEquals(abs13, abs1slash3);
56+
assertEquals(abs13, abs1otherslash3);
57+
assertEquals(abs12up3, abs12up3otherslash);
5458
// Not filtering out empty elements for joining will cause this to fail
5559
assertFalse(fs.getPath("", "one", "two").isAbsolute());
5660

0 commit comments

Comments
 (0)