# HG changeset patch # User Arun Giridhar # Date 1714503396 14400 # Node ID 1ca9b217a5e680b1e45bc4a27e3881e9ad02dcc5 # Parent 13695d1ea7f2c1dc70adbec5d6d157341ec0f0a1 print_usage.m: Speed up Texinfo processing for common cases Previously, `print_usage` was always calling `__makeinfo__` which in turn calls `system ("makeinfo")`. This turned out to be time-consuming, especially for `make check`, where profiling showed that a majority of the time was being spent in `system ("makeinfo")`. Discussion: https://octave.discourse.group/t/calls-to-system-slowing-down-make-check/5563 This patch converts the most commonly occurring `print_usage` Texinfo commands to plain text without requiring the full makeinfo. As a consequence, `make check` is sped up by 2X to 2.5X on Linux and by 5X to 10X on Windows. * print_usage.m: ** New function `__makeinfo_restricted__` to process specific Texinfo commands. ** Use that function in `get_usage_texinfo` and fall back to `__makeinfo__` if it fails. * movfun.m: Replace a nested `@var` occurrence that caused problems for the new code. diff -r 13695d1ea7f2 -r 1ca9b217a5e6 scripts/help/print_usage.m --- a/scripts/help/print_usage.m Mon Apr 29 16:25:41 2024 -0400 +++ b/scripts/help/print_usage.m Tue Apr 30 14:56:36 2024 -0400 @@ -142,9 +142,87 @@ endif endfor - ## Run makeinfo to generate plain text - [retval, status] = __makeinfo__ (buffer, "plain text"); + ## Generate plain text from the markup. + [retval, status] = __makeinfo_restricted__ (buffer); + if (status != 0) # something went wrong in the restricted conversion. + ## Use the full conversion. + [retval, status] = __makeinfo__ (buffer, "plain text"); + endif + +endfunction + +function [retval, status] = __makeinfo_restricted__ (buffer) + ## This function converts the very narrow subset of Texinfo commands + ## that are actually used by `print_usage` into plain text, + ## without requiring a slow call to `system ("makeinfo")`. + ## + ## As of April 2024, only the following Texinfo commands are being used + ## by print_usage strings in Octave core: + ## + ## @deftypefn, @deftypefnx, @end deftypefn, @var, @qcode, @dots, @, @@ + ## + ## Note: this function is meant only for print_usage (), not for help (), + ## which continues to use the full makeinfo. + + retval = ""; + status = -1; # assume failure to convert + + ## The simple replacements first. + buffer = strrep (buffer, "@deftypefnx", ""); + buffer = strrep (buffer, "@end deftypefn\n", ""); + buffer = strrep (buffer, "@deftypefn ", ""); + buffer = strrep (buffer, "@qcode", ""); + buffer = strrep (buffer, "@dots", "..."); + + ## Capitalize variable names, so "@var{foo}" becomes "@var{FOO}". + ## FIXME: Replace this loop with a call to regexprep once transformation + ## features are available. + for j = strfind (buffer, "@var") # each instance of @var + ## Upper-case the part between the relevant braces. + k = find (buffer(j:end) == '}', 1) + j - 1; + buffer((j+5):(k-1)) = upper (buffer((j+5):(k-1))); + endfor + ## Don't need @var any more, nor any braces. + buffer = strrep (buffer, "@var", ""); + buffer(buffer == '{' | buffer == '}') = []; + + ## There should not be any Texinfo commands remaining at this point. + ## Search for this with the regex "@[a-z]" because other instances of @ + ## occur next to upper case letters or non-letters by this point. + if (any (regexp (buffer, "@[a-z]"))) + ## There is some Texinfo command in the deftypefn line + ## outside the scope of this restricted function, + ## so return with status set to failure. + return + endif + + ## Process any remaining @ signs. + ## Context: A line like this: + ## setappdata (H, @NAME1, NAME2, ...@, @VALUE1, VALUE2, ...@) + ## should become + ## setappdata (H, {NAME1, NAME2, ...}, {VALUE1, VALUE2, ...}) + ## But a line like this: + ## A = cellfun (@@FCN, C) + ## should become: + ## A = cellfun (@FCN, C) + ## and not this: + ## A = cellfun ({}FCN, C) + ## Currently the code uses a guard string to protect the @@, + ## then replaces @ with { or }, then unprotects the @@ and changes it to @. + ## FIXME: Simplify this conversion sequence if possible. + + if (any (buffer == '@')) + guardstring = "ZAQWSXCDERFV"; # some improbable sequence + buffer = strrep (buffer, "@@", guardstring); + ff = find (buffer == '@'); # these show up in pairs, verified with assert + buffer(ff(1:2:end)) = '{'; # odd-numbered locations become { + buffer(ff(2:2:end)) = '}'; # even-numbered ones become } + buffer = strrep (buffer, guardstring, "@"); + endif + + retval = buffer; + status = 0; # == success endfunction function [retval, status] = get_usage_html (help_text, max_len) diff -r 13695d1ea7f2 -r 1ca9b217a5e6 scripts/signal/movfun.m --- a/scripts/signal/movfun.m Mon Apr 29 16:25:41 2024 -0400 +++ b/scripts/signal/movfun.m Tue Apr 30 14:56:36 2024 -0400 @@ -25,7 +25,7 @@ ## -*- texinfo -*- ## @deftypefn {} {@var{y} =} movfun (@var{fcn}, @var{x}, @var{wlen}) -## @deftypefnx {} {@var{y} =} movfun (@var{fcn}, @var{x}, @var{[@var{nb}, @var{na}}]) +## @deftypefnx {} {@var{y} =} movfun (@var{fcn}, @var{x}, [@var{nb}, @var{na}]) ## @deftypefnx {} {@var{y} =} movfun (@dots{}, "@var{property}", @var{value}) ## ## Apply function @var{fcn} to a moving window of length @var{wlen} on data