Skip to content

Commit ab82f10

Browse files
committed
[opt] major speedup by 3x-4x via inlining short functions and caching
1 parent 4a9eabd commit ab82f10

10 files changed

Lines changed: 2745 additions & 1416 deletions

File tree

encodevarname.m

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
%
55
% Encode an invalid variable name using a hex-format for bi-directional
66
% conversions.
7-
7+
%
88
% This function is sensitive to the default charset
99
% settings in MATLAB, please call feature('DefaultCharacterSet','utf8')
1010
% to set the encoding to UTF-8 before calling this function.
@@ -37,21 +37,39 @@
3737
% License: GPLv3 or 3-clause BSD license, see https://github.com/NeuroJSON/easyh5 for details
3838
%
3939

40-
if (~isvarname(str(1)))
40+
% Fast path: check first character directly instead of calling isvarname
41+
c1 = str(1);
42+
if ~((c1 >= 'a' && c1 <= 'z') || (c1 >= 'A' && c1 <= 'Z'))
43+
% First char is not a letter - need to encode it
4144
if (exist('unicode2native', 'builtin'))
42-
str = sprintf('x0x%s_%s', sprintf('%X', unicode2native(str(1))), str(2:end));
45+
str = sprintf('x0x%s_%s', sprintf('%X', unicode2native(c1)), str(2:end));
4346
else
44-
str = sprintf('x0x%X_%s', char(str(1)) + 0, str(2:end));
47+
str = sprintf('x0x%X_%s', c1 + 0, str(2:end));
4548
end
4649
end
47-
if (isvarname(str))
48-
return
50+
51+
% Fast validation: check if all remaining chars are valid (alphanumeric or underscore)
52+
% This is faster than calling isvarname for simple cases
53+
len = length(str);
54+
if len <= 63
55+
isvalid = true;
56+
for i = 1:len
57+
c = str(i);
58+
if ~((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')
59+
isvalid = false;
60+
break
61+
end
62+
end
63+
if isvalid
64+
return
65+
end
4966
end
67+
68+
% Slow path: has invalid characters, need full encoding
5069
if (exist('unicode2native', 'builtin'))
5170
str = regexprep(str, '([^0-9A-Za-z_])', '_0x${sprintf(''%X'',unicode2native($1))}_');
5271
else
5372
cpos = find(~ismember(str, ['0':'9', 'A':'Z', 'a':'z', '_']));
54-
% cpos=regexp(str,'[^0-9A-Za-z_]');
5573
if (isempty(cpos))
5674
return
5775
end

0 commit comments

Comments
 (0)