Skip to content

Commit a3bd4ea

Browse files
committed
canonical,resolve: faster, simpler
1 parent c5d6494 commit a3bd4ea

File tree

5 files changed

+46
-33
lines changed

5 files changed

+46
-33
lines changed

+stdlib/canonical.m

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,23 @@
99
%%% Inputs
1010
% * p: path to make canonical
1111
% * strict: if true, only return canonical path if it exists. If false, return normalized path if path does not exist.
12-
% * backend: backend to use
1312
%%% Outputs
1413
% * c: canonical path, if determined
15-
% * b: backend used
1614

17-
function [c, b] = canonical(p, strict, backend)
15+
function c = canonical(p, strict)
1816
arguments
1917
p string
2018
strict (1,1) logical = false
21-
backend (1,:) string = ["native", "legacy"]
2219
end
2320

24-
[fun, b] = hbackend(backend, "canonical");
25-
26-
if isscalar(p) || b == "native"
27-
c = fun(p, strict);
28-
else
29-
c = arrayfun(fun, p, repmat(strict, size(p)));
21+
try
22+
c = stdlib.native.canonical(p, strict);
23+
catch e
24+
if e.identifier == "MATLAB:UndefinedFunction"
25+
c = stdlib.legacy.canonical(p, strict);
26+
else
27+
rethrow(e)
28+
end
3029
end
3130

3231
end

+stdlib/resolve.m

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,18 @@
33
% effectively canonical(absolute(p))
44
%%% Inputs
55
% * p: path to make absolute
6-
% * backend: backend to use
76
%%% Outputs
87
% * c: resolved path
9-
% * b: backend used
108

119
% distinct from canonical(), resolve() always returns absolute path
1210
% non-existant path is made absolute relative to pwd
1311

14-
function [r, b] = resolve(p, strict, backend)
12+
function r = resolve(p, strict)
1513
arguments
1614
p string
1715
strict (1,1) logical = false
18-
backend (1,:) string = ["native", "legacy"]
1916
end
2017

21-
[r, b] = stdlib.canonical(stdlib.absolute(p), strict, backend);
18+
r = stdlib.canonical(stdlib.absolute(p), strict);
2219

2320
end

example/bench_canonical.m

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function bench_canonical()
2+
3+
in = mfilename("fullpath") + ".m";
4+
r = fileparts(fileparts(in));
5+
addpath(r)
6+
obj = onCleanup(@() rmpath(r));
7+
8+
f = timeit(@() stdlib.canonical(in)) * 1e3;
9+
n = timeit(@() stdlib.native.canonical(in)) * 1e3;
10+
l = timeit(@() stdlib.legacy.canonical(in)) * 1e3;
11+
12+
fprintf('Full %f\nNative: %f\nLegacy: %f\n', f, n, l);
13+
14+
end

test/TestCanonical.m

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
{"not-exist/a/..", "not-exist"}, ...
1111
{"./not-exist", "not-exist"}
1212
};
13-
backend = init_backend({'native', 'legacy'}, 'native', ~isMATLABReleaseOlderThan('R2024a'))
1413
end
1514

1615
methods(TestClassSetup)
@@ -24,16 +23,21 @@ function test_dirs(tc)
2423

2524
methods(Test)
2625

27-
function test_canonical(tc, p, backend)
28-
c = stdlib.canonical(p{1}, false, backend);
26+
function test_canonical(tc, p)
27+
c = stdlib.canonical(p{1}, false);
28+
tc.verifyEqual(c, p{2})
29+
end
30+
31+
function test_legacy_canonical(tc, p)
32+
c = stdlib.legacy.canonical(p{1}, false);
2933
tc.verifyEqual(c, p{2})
3034
end
3135

3236

33-
function test_canonical_array(tc, backend)
37+
function test_canonical_array(tc)
3438
in = ["", "hi", "/ok", "not-exist/a/.."];
3539

36-
c = stdlib.canonical(in, false, backend);
40+
c = stdlib.canonical(in, false);
3741
exp = ["", "hi", filesep + "ok", "not-exist"];
3842
tc.verifyEqual(c, exp)
3943
end

test/TestResolve.m

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
properties (TestParameter)
55
p = {'', "", ".", ".."}
6-
backend = init_backend({'native', 'legacy'}, 'native', ~isMATLABReleaseOlderThan('R2024a'))
76
end
87

98
methods(TestClassSetup)
@@ -17,49 +16,49 @@ function test_dirs(tc)
1716

1817
methods (Test)
1918

20-
function test_resolve_relative(tc, backend)
19+
function test_resolve_relative(tc)
2120
import matlab.unittest.constraints.StartsWithSubstring
2221
import matlab.unittest.constraints.ContainsSubstring
2322

2423
% all non-existing files
2524

26-
pabs = stdlib.resolve('2foo', false, backend);
27-
pabs2 = stdlib.resolve('4foo', false, backend);
25+
pabs = stdlib.resolve('2foo', false);
26+
pabs2 = stdlib.resolve('4foo', false);
2827
tc.verifyThat(pabs, ~StartsWithSubstring("2"))
2928
tc.verifyThat(pabs, StartsWithSubstring(extractBefore(pabs2, 3)))
3029

31-
par1 = stdlib.resolve("../2foo", false, backend);
30+
par1 = stdlib.resolve("../2foo", false);
3231
tc.verifyNotEmpty(par1)
3332
tc.verifyThat(par1, ~ContainsSubstring(".."))
3433

35-
par2 = stdlib.resolve("../4foo", false, backend);
34+
par2 = stdlib.resolve("../4foo", false);
3635
tc.verifyThat(par2, StartsWithSubstring(extractBefore(pabs2, 3)))
3736

38-
pt1 = stdlib.resolve("bar/../2foo", false, backend);
37+
pt1 = stdlib.resolve("bar/../2foo", false);
3938
tc.verifyNotEmpty(pt1)
4039
tc.verifyThat(pt1, ~ContainsSubstring(".."))
4140

42-
va = stdlib.resolve("2foo", false, backend);
43-
vb = stdlib.resolve("4foo", false, backend);
41+
va = stdlib.resolve("2foo", false);
42+
vb = stdlib.resolve("4foo", false);
4443
tc.verifyThat(va, ~StartsWithSubstring("2"))
4544
tc.verifyThat(va, StartsWithSubstring(extractBefore(vb, 3)))
4645

4746
end
4847

49-
function test_resolve_fullpath(tc, p, backend)
48+
function test_resolve_fullpath(tc, p)
5049

5150
a = p;
5251
switch a
5352
case {'', "", '.', "."}, b = string(pwd());
5453
case {'..', ".."}, b = string(fileparts(pwd()));
5554
end
5655

57-
tc.verifyEqual(stdlib.resolve(a, false, backend), b)
56+
tc.verifyEqual(stdlib.resolve(a, false), b)
5857
end
5958

60-
function test_resolve_array(tc, backend)
59+
function test_resolve_array(tc)
6160
in = ["", "hi", "/ok", "not-exist/a/.."];
62-
c = stdlib.resolve(in, false, backend);
61+
c = stdlib.resolve(in, false);
6362

6463
exp = [pwd(), fullfile(pwd(), "hi"), filesep + "ok", fullfile(pwd(), "not-exist")];
6564
if ispc()

0 commit comments

Comments
 (0)