Skip to content

Commit 121b218

Browse files
committed
is_{exe,readable,writable} 40x faster than native
1 parent 091b870 commit 121b218

File tree

12 files changed

+58
-52
lines changed

12 files changed

+58
-52
lines changed

+stdlib/+legacy/file_attributes.m

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@
44
end
55
% need arguments and stdlib.strempty for Matlab < R2020b
66

7-
assert(~stdlib.strempty(p), 'Path must not be empty.');
7+
a = struct.empty;
8+
9+
if stdlib.strempty(p)
10+
return
11+
end
812

913
[status, s] = fileattrib(p);
1014

11-
assert(status == 1, "'%s' is not a file or directory.", p);
15+
if status ~= 1
16+
return
17+
end
1218

1319
a = s;
1420
for n = ["GroupRead", "GroupWrite", "GroupExecute", "OtherRead", "OtherWrite", "OtherExecute"]

+stdlib/+legacy/is_exe.m

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
return
77
end
88

9-
if ~isfile(file)
10-
return
11-
end
12-
139
a = stdlib.legacy.file_attributes(file);
14-
y = a.UserExecute || a.GroupExecute || a.OtherExecute;
10+
11+
if ~isempty(a) && ~a.directory
12+
y = a.UserExecute || a.GroupExecute || a.OtherExecute;
13+
end
1514

1615
end

+stdlib/+legacy/is_readable.m

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
function y = is_readable(file)
2-
arguments
3-
file (1,1) string
4-
end
52

6-
if stdlib.exists(file)
7-
a = stdlib.legacy.file_attributes(file);
3+
y = false;
4+
5+
a = stdlib.legacy.file_attributes(file);
6+
7+
if ~isempty(a)
88
y = a.UserRead || a.GroupRead || a.OtherRead;
9-
else
10-
y = false;
119
end
1210

1311
end

+stdlib/+legacy/is_writable.m

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
function y = is_writable(file)
2-
arguments
3-
file (1,1) string
4-
end
52

6-
if stdlib.exists(file)
7-
a = stdlib.legacy.file_attributes(file);
3+
y = false;
4+
5+
a = stdlib.legacy.file_attributes(file);
6+
7+
if ~isempty(a)
88
y = a.UserWrite || a.GroupWrite || a.OtherWrite;
9-
else
10-
y = false;
119
end
1210

1311
end

+stdlib/get_permissions.m

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,20 @@
1313
file (1,1) string
1414
end
1515

16-
perm = '';
17-
b = '';
1816

19-
if stdlib.exists(file)
20-
try
21-
perm = perm2char(filePermissions(file));
22-
b = 'native';
23-
catch e
24-
if e.identifier ~= "MATLAB:UndefinedFunction"
17+
try
18+
perm = perm2char(filePermissions(file));
19+
b = 'native';
20+
catch e
21+
switch e.identifier
22+
case 'MATLAB:UndefinedFunction'
23+
perm = perm2char(stdlib.legacy.file_attributes(file));
24+
b = 'legacy';
25+
case 'MATLAB:io:filesystem:filePermissions:CannotFindLocation'
26+
perm = '';
27+
b = '';
28+
otherwise
2529
rethrow(e)
26-
end
27-
28-
perm = perm2char(stdlib.legacy.file_attributes(file));
29-
b = 'legacy';
3030
end
3131
end
3232

+stdlib/is_exe.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
%%% Outputs
77
% ok: true if path is a file and has executable permissions
88
%
9-
% the legacy backend is actually significantly faster for single files
9+
% the legacy backend is like 40x faster than native.
1010

1111
function [ok, b] = is_exe(file)
1212
arguments

+stdlib/is_readable.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
%%% Outputs
66
% ok: true if file is readable
77
%
8-
% the legacy backend is actually significantly faster for single files
8+
% the legacy backend is like 40x faster than native
99

1010
function [ok, b] = is_readable(file)
1111
arguments

+stdlib/is_writable.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
%%% Outputs
66
% * ok: true if file is writable
77
%
8-
% the legacy backend is actually significantly faster for single files
8+
% the legacy backend is like 40x faster than native
99

1010
function [ok, b] = is_writable(file)
1111
arguments

+stdlib/private/perm2char.m

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,28 @@
22

33
function p = perm2char(v)
44
arguments
5-
v (1,1)
5+
v {mustBeScalarOrEmpty}
6+
end
7+
8+
if isempty(v)
9+
p = '';
10+
return
611
end
712

813

914
p = '---------';
1015

11-
if isa(v, "matlab.io.WindowsPermissions") || isa(v, "matlab.io.UnixPermissions")
12-
if v.Readable, p(1) = 'r'; end
13-
if v.Writable, p(2) = 'w'; end
14-
elseif isstruct(v)
15-
if v.UserRead, p(1) = 'r'; end
16-
if v.UserWrite, p(2) = 'w'; end
17-
else
18-
% cloud / remote locations we don't handle
19-
p = '';
20-
return
16+
switch class(v)
17+
case {'matlab.io.WindowsPermissions', 'matlab.io.UnixPermissions'}
18+
if v.Readable, p(1) = 'r'; end
19+
if v.Writable, p(2) = 'w'; end
20+
case 'struct'
21+
if v.UserRead, p(1) = 'r'; end
22+
if v.UserWrite, p(2) = 'w'; end
23+
otherwise
24+
% cloud / remote locations we don't handle
25+
p = '';
26+
return
2127
end
2228

2329
if isa(v, "matlab.io.WindowsPermissions") || ispc()

example/BenchmarkIsExe.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ function bench_exist(tc, fun)
1717
e = e + ".exe";
1818
end
1919

20-
tc.startMeasuring()
21-
y = fun(e);
22-
tc.stopMeasuring()
20+
while tc.keepMeasuring()
21+
y = fun(e);
22+
end
2323

2424
tc.verifyEqual(y, true)
2525
end

0 commit comments

Comments
 (0)