Skip to content

Commit 23432a3

Browse files
committed
non-java normalize, more than 10x faster
1 parent a17439a commit 23432a3

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

+stdlib/canonical.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
else
4646
% for non-existing path, return normalized relative path
4747
% like C++ filesystem weakly_canonical()
48-
c = stdlib.normalize(c);
48+
c = stdlib.normalize(c, use_java);
4949
return
5050
end
5151
end

+stdlib/normalize.m

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function n = normalize(p)
1+
function n = normalize(p, use_java)
22
%% normalize(p)
33
% normalize(p) remove redundant elements of path p
44
% path need not exist, normalized path is returned
@@ -10,9 +10,51 @@
1010
% https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/nio/file/Path.html#normalize()
1111
arguments
1212
p (1,1) string
13+
use_java (1,1) logical = false
1314
end
1415

15-
n = stdlib.posix(java.io.File(p).toPath().normalize());
16+
if use_java
17+
n = stdlib.posix(java.io.File(p).toPath().normalize());
18+
else
19+
20+
n = stdlib.posix(p);
21+
22+
% use split to remove /../ and /./ and duplicated /
23+
parts = split(n, "/");
24+
i0 = 1;
25+
if startsWith(n, "/")
26+
n = "/";
27+
elseif ispc && strlength(n) >= 2 && isletter(extractBetween(n, 1, 1)) && extractBetween(n, 2, 2) == ":"
28+
n = parts(1);
29+
i0 = 2;
30+
else
31+
n = "";
32+
end
33+
34+
for i = i0:length(parts)
35+
if parts(i) == ".."
36+
if n == ""
37+
n = parts(i);
38+
elseif endsWith(n, "..")
39+
n = n + "/" + parts(i);
40+
else
41+
j = strfind(n, "/");
42+
if isempty(j)
43+
n = "";
44+
else
45+
n = extractBefore(n, j(end));
46+
end
47+
end
48+
elseif all(parts(i) ~= [".", ""])
49+
if n == ""
50+
n = parts(i);
51+
else
52+
n = n + "/" + parts(i);
53+
end
54+
end
55+
end
56+
57+
end
1658

1759
if(strlength(n) == 0), n = "."; end
1860

+stdlib/relative_to.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
end
66

77
% must remove trailing slashes
8-
base = stdlib.normalize(base);
9-
other = stdlib.normalize(other);
8+
base = stdlib.normalize(base, true);
9+
other = stdlib.normalize(other, true);
1010

1111
if base == other
1212
r = ".";

0 commit comments

Comments
 (0)