# HG changeset patch
# User Daniel Kraft
# Date 1462439120 -7200
# Thu May 05 11:05:20 2016 +0200
# Node ID ff4c0d97dd91613f7efa0d30ced855e4a4e469d5
# Parent 5e083d07ba35f423983e191bbe37ebecca4d8043
[maint] Move profiler scripts to own directory.
* scripts/profiler: New directory for profiler-related m files.
* scripts/general/profile.m, profexplore.m, profshow.m:
Move away to the new directory.
* scripts/general/module.mk: Remove moved m files.
* scripts/module.mk: Add new directory.
diff -r 5e083d07ba35 -r ff4c0d97dd91 scripts/general/module.mk
--- a/scripts/general/module.mk Tue May 03 15:19:47 2016 -0700
+++ b/scripts/general/module.mk Thu May 05 11:05:20 2016 +0200
@@ -60,9 +60,6 @@
scripts/general/polyarea.m \
scripts/general/postpad.m \
scripts/general/prepad.m \
- scripts/general/profexplore.m \
- scripts/general/profile.m \
- scripts/general/profshow.m \
scripts/general/quadgk.m \
scripts/general/quadl.m \
scripts/general/quadv.m \
diff -r 5e083d07ba35 -r ff4c0d97dd91 scripts/general/profexplore.m
--- a/scripts/general/profexplore.m Tue May 03 15:19:47 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-## Copyright (C) 2012-2015 Daniel Kraft
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING. If not, see
-## .
-
-## -*- texinfo -*-
-## @deftypefn {} {} profexplore ()
-## @deftypefnx {} {} profexplore (@var{data})
-## Interactively explore hierarchical profiler output.
-##
-## Assuming @var{data} is the structure with profile data returned by
-## @code{profile (@qcode{"info"})}, this command opens an interactive prompt
-## that can be used to explore the call-tree. Type @kbd{help} to get a list
-## of possible commands. If @var{data} is omitted, @code{profile ("info")}
-## is called and used in its place.
-## @seealso{profile, profshow}
-## @end deftypefn
-
-## Built-in profiler.
-## Author: Daniel Kraft
-
-function profexplore (data)
-
- if (nargin == 0)
- data = profile ("info");
- elseif (nargin != 1)
- print_usage ();
- endif
-
- ## The actual work is done by a recursive worker function, since that
- ## is an easy way to traverse the tree datastructure. Here, we just check
- ## the arguments (already done) and give over to it.
-
- __profexplore_worker (data.FunctionTable, data.Hierarchical, "Top\n", " ");
-
-endfunction
-
-## This is the worker function. tree is the current subtree we want to
-## display / explore. parents is a string containing the already "rendered"
-## data for the parents which is displayed on top of the list of current
-## children. prefix is the prefix to add to each line rendered; this
-## is just a string of spaces to get indentation right.
-##
-## Returning 0 indicates that the user requested to totally exit the
-## explorer, thus also all higher levels should exit immediately. An integer
-## greater zero indicates to exit that many levels since the user wants to go
-## up (but not necessarily quit).
-
-function rv = __profexplore_worker (fcn_table, tree, parents, prefix)
-
- ## Sort children by total time.
- times = -[ tree.TotalTime ];
- [~, p] = sort (times);
- tree = tree(p);
-
- while (true)
-
- printf ("\n%s", parents);
- strings = cell (length (tree), 1);
- for i = 1 : length (tree)
- strings{i} = sprintf ("%s: %d calls, %.3f total, %.3f self", ...
- fcn_table(tree(i).Index).FunctionName, ...
- tree(i).NumCalls, ...
- tree(i).TotalTime, tree(i).SelfTime);
- printf ("%s%d) %s\n", prefix, i, strings{i});
- endfor
- printf ("\n");
-
- cmd = input ("profexplore> ", "s");
- option = fix (str2double (cmd));
-
- if (strcmp (cmd, "exit") || strcmp (cmd, "quit"))
- rv = 0;
- return;
- elseif (strcmp (cmd, "help"))
- printf ("\nCommands for profile explorer:\n\n");
- printf ("exit Return to Octave prompt.\n");
- printf ("quit Return to Octave prompt.\n");
- printf ("help Display this help message.\n");
- printf ("up [N] Go up N levels, where N is an integer. Default is 1.\n");
- printf ("N Go down a level into option N.\n");
- elseif (! isnan (option))
- if (option < 1 || option > length (tree))
- printf ("The chosen option is out of range!\n");
- else
- newParents = sprintf ("%s%s%s\n", parents, prefix, strings{option});
- newPrefix = sprintf ("%s ", prefix);
-
- rv = __profexplore_worker (fcn_table, tree(option).Children, ...
- newParents, newPrefix);
-
- if (rv == 0)
- return;
- elseif (rv > 1)
- rv -= 1;
- return;
- else
- assert (rv == 1);
- ## It was requested to return to this level, so just stay.
- endif
- endif
- elseif (length (cmd) >= 2 && strcmp (substr (cmd, 1, 2), "up"))
- if (length (cmd) == 2)
- rv = 1;
- return;
- endif
-
- if (length (cmd) > 3 && cmd(3) == ' ')
- opt = fix (str2double (substr (cmd, 3)));
- if (! isnan (opt) && opt > 0)
- rv = opt;
- return;
- endif
- endif
-
- printf ("Invalid 'up' command. Type 'help' for further");
- printf (" information.\n");
- else
- printf ("Unrecognized input. Type 'help' to get a list of possible");
- printf (" commands.\n");
- endif
-
- endwhile
-endfunction
-
diff -r 5e083d07ba35 -r ff4c0d97dd91 scripts/general/profile.m
--- a/scripts/general/profile.m Tue May 03 15:19:47 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-## Copyright (C) 2012-2015 Daniel Kraft
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING. If not, see
-## .
-
-## -*- texinfo -*-
-## @deftypefn {} {} profile on
-## @deftypefnx {} {} profile off
-## @deftypefnx {} {} profile resume
-## @deftypefnx {} {} profile clear
-## @deftypefnx {} address@hidden =} profile ("status")
-## @deftypefnx {} address@hidden =} profile ("info")
-## Control the built-in profiler.
-##
-## @table @code
-## @item profile on
-## Start the profiler, clearing all previously collected data if there is any.
-##
-## @item profile off
-## Stop profiling. The collected data can later be retrieved and examined
-## with @code{T = profile ("info")}.
-##
-## @item profile clear
-## Clear all collected profiler data.
-##
-## @item profile resume
-## Restart profiling without clearing the old data. All newly collected
-## statistics are added to the existing ones.
-##
-## @item @var{S} = profile ("status")
-## Return a structure with information about the current status of the
-## profiler. At the moment, the only field is @code{ProfilerStatus} which is
-## either @qcode{"on"} or @qcode{"off"}.
-##
-## @item @var{T} = profile ("info")
-## Return the collected profiling statistics in the structure @var{T}. The
-## flat profile is returned in the field @code{FunctionTable} which is an
-## array of structures, each entry corresponding to a function which was called
-## and for which profiling statistics are present. In addition, the field
-## @code{Hierarchical} contains the hierarchical call tree. Each node has an
-## index into the @code{FunctionTable} identifying the function it corresponds
-## to as well as data fields for number of calls and time spent at this level
-## in the call tree.
-## @seealso{profshow, profexplore}
-## @end table
-## @end deftypefn
-
-## Built-in profiler.
-## Author: Daniel Kraft
-
-function retval = profile (option)
-
- if (nargin != 1)
- print_usage ();
- endif
-
- switch (option)
- case "on"
- __profiler_reset__ ();
- __profiler_enable__ (true);
-
- case "off"
- __profiler_enable__ (false);
-
- case "clear"
- __profiler_reset__ ();
-
- case "resume"
- __profiler_enable__ (true);
-
- case "status"
- enabled = __profiler_enable__ ();
- if (enabled)
- enabled = "on";
- else
- enabled = "off";
- endif
- retval = struct ("ProfilerStatus", enabled);
-
- case "info"
- [flat, tree] = __profiler_data__ ();
- retval = struct ("FunctionTable", flat, "Hierarchical", tree);
-
- otherwise
- warning ("profile: Unrecognized option '%s'", option);
- print_usage ();
-
- endswitch
-
-endfunction
-
-
-%!demo
-%! profile on;
-%! A = rand (100);
-%! B = expm (A);
-%! profile off;
-%! profile resume;
-%! C = sqrtm (A);
-%! profile off;
-%! T = profile ("info");
-%! profshow (T);
-
-%!test
-%! on_struct.ProfilerStatus = "on";
-%! off_struct.ProfilerStatus = "off";
-%! profile ("on");
-%! result = logm (rand (200) + 10 * eye (200));
-%! assert (profile ("status"), on_struct);
-%! profile ("off");
-%! assert (profile ("status"), off_struct);
-%! profile ("resume");
-%! result = logm (rand (200) + 10 * eye (200));
-%! profile ("off");
-%! assert (profile ("status"), off_struct);
-%! info = profile ("info");
-%! assert (isstruct (info));
-%! assert (size (info), [1, 1]);
-%! assert (fieldnames (info), {"FunctionTable"; "Hierarchical"});
-%! ftbl = info.FunctionTable;
-%! assert (fieldnames (ftbl), {"FunctionName"; "TotalTime"; "NumCalls"; "IsRecursive"; "Parents"; "Children"});
-%! hier = info.Hierarchical;
-%! assert (fieldnames (hier), {"Index"; "SelfTime"; "TotalTime"; "NumCalls"; "Children"});
-%! profile ("clear");
-%! info = profile ("info");
-%! assert (isstruct (info));
-%! assert (size (info), [1, 1]);
-%! assert (fieldnames (info), {"FunctionTable"; "Hierarchical"});
-%! ftbl = info.FunctionTable;
-%! assert (size (ftbl), [0, 1]);
-%! assert (fieldnames (ftbl), {"FunctionName"; "TotalTime"; "NumCalls"; "IsRecursive"; "Parents"; "Children"});
-%! hier = info.Hierarchical;
-%! assert (size (hier), [0, 1]);
-%! assert (fieldnames (hier), {"Index"; "SelfTime"; "NumCalls"; "Children"});
-
-## Test input validation
-%!error profile ()
-%!error profile ("on", 2)
-%!error profile ("INVALID_OPTION")
-
diff -r 5e083d07ba35 -r ff4c0d97dd91 scripts/general/profshow.m
--- a/scripts/general/profshow.m Tue May 03 15:19:47 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-## Copyright (C) 2012-2014 Daniel Kraft
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING. If not, see
-## .
-
-## -*- texinfo -*-
-## @deftypefn {} {} profshow (@var{data})
-## @deftypefnx {} {} profshow (@var{data}, @var{n})
-## @deftypefnx {} {} profshow ()
-## @deftypefnx {} {} profshow (@var{n})
-## Display flat per-function profiler results.
-##
-## Print out profiler data (execution time, number of calls) for the most
-## critical @var{n} functions. The results are sorted in descending order by
-## the total time spent in each function. If @var{n} is unspecified it
-## defaults to 20.
-##
-## The input @var{data} is the structure returned by @code{profile ("info")}.
-## If unspecified, @code{profshow} will use the current profile dataset.
-##
-## The attribute column displays @samp{R} for recursive functions, and is blank
-## for all other function types.
-## @seealso{profexplore, profile}
-## @end deftypefn
-
-## Built-in profiler.
-## Author: Daniel Kraft
-
-function profshow (data, n = 20)
-
- if (nargin > 2)
- print_usage ();
- endif
-
- if (nargin == 0)
- data = profile ("info");
- elseif (nargin == 1 && ! isstruct (data))
- n = data;
- data = profile ("info");
- endif
-
- n = fix (n);
- if (! isscalar (n) || ! isreal (n) || ! (n > 0))
- error ("profile: N must be a positive integer");
- endif
-
- m = length (data.FunctionTable);
- n = min (n, m);
-
- ## We want to sort by times in descending order. For this, extract the
- ## times to an array, then sort this, and use the resulting index permutation
- ## to print out our table.
- times = [ data.FunctionTable.TotalTime ];
- totalTime = sum (times);
-
- [~, p] = sort (times, "descend");
-
- ## For printing the table, find out the maximum length of a function name
- ## so that we can proportion the table accordingly. Based on this,
- ## we can build the format used for printing table rows.
- nameLen = max (length ("Function"),
- columns (char (data.FunctionTable(p(1:n)).FunctionName)));
- headerFormat = sprintf ("%%4s %%%ds %%4s %%12s %%10s %%12s\n", nameLen);
- rowFormat = sprintf ("%%4d %%%ds %%4s %%12.3f %%10.2f %%12d\n", nameLen);
-
- printf (headerFormat, ...
- "#", "Function", "Attr", "Time (s)", "Time (%)", "Calls");
- printf ("%s\n", repmat ("-", 1, nameLen + 2 * 5 + 11 + 2 * 13));
-
- for i = 1 : n
- row = data.FunctionTable(p(i));
- timePercent = 100 * row.TotalTime / totalTime;
- attr = "";
- if (row.IsRecursive)
- attr = "R";
- endif
- printf (rowFormat, p(i), row.FunctionName, attr,
- row.TotalTime, timePercent, row.NumCalls);
- endfor
-
-endfunction
-
-
-%!demo
-%! profile on;
-%! A = rand (100);
-%! B = expm (A);
-%! profile off;
-%! T = profile ("info");
-%! profshow (T, 10);
-
-%!demo
-%! profile on;
-%! expm (rand (500) + eye (500));
-%! profile off;
-%! profshow (profile ("info"), 5);
-
-%!error profshow (1, 2, 3)
-%!error profshow (struct (), ones (2))
-%!error profshow (struct (), 1+i)
-%!error profshow (struct (), -1)
-
diff -r 5e083d07ba35 -r ff4c0d97dd91 scripts/module.mk
--- a/scripts/module.mk Tue May 03 15:19:47 2016 -0700
+++ b/scripts/module.mk Thu May 05 11:05:20 2016 +0200
@@ -25,6 +25,7 @@
include scripts/plot/util/module.mk
include scripts/polynomial/module.mk
include scripts/prefs/module.mk
+include scripts/profiler/module.mk
include scripts/set/module.mk
include scripts/signal/module.mk
include scripts/sparse/module.mk
diff -r 5e083d07ba35 -r ff4c0d97dd91 scripts/profiler/module.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/profiler/module.mk Thu May 05 11:05:20 2016 +0200
@@ -0,0 +1,16 @@
+FCN_FILE_DIRS += \
+ scripts/profiler
+
+scripts_profiler_FCN_FILES = \
+ scripts/profiler/profexplore.m \
+ scripts/profiler/profile.m \
+ scripts/profiler/profshow.m
+
+scripts_profilerdir = $(fcnfiledir)/profiler
+
+scripts_profiler_DATA = $(scripts_profiler_FCN_FILES)
+
+FCN_FILES += \
+ $(scripts_profiler_FCN_FILES)
+
+DIRSTAMP_FILES += scripts/profiler/$(octave_dirstamp)
diff -r 5e083d07ba35 -r ff4c0d97dd91 scripts/profiler/profexplore.m
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/profiler/profexplore.m Thu May 05 11:05:20 2016 +0200
@@ -0,0 +1,138 @@
+## Copyright (C) 2012-2015 Daniel Kraft
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING. If not, see
+## .
+
+## -*- texinfo -*-
+## @deftypefn {} {} profexplore ()
+## @deftypefnx {} {} profexplore (@var{data})
+## Interactively explore hierarchical profiler output.
+##
+## Assuming @var{data} is the structure with profile data returned by
+## @code{profile (@qcode{"info"})}, this command opens an interactive prompt
+## that can be used to explore the call-tree. Type @kbd{help} to get a list
+## of possible commands. If @var{data} is omitted, @code{profile ("info")}
+## is called and used in its place.
+## @seealso{profile, profshow}
+## @end deftypefn
+
+## Built-in profiler.
+## Author: Daniel Kraft
+
+function profexplore (data)
+
+ if (nargin == 0)
+ data = profile ("info");
+ elseif (nargin != 1)
+ print_usage ();
+ endif
+
+ ## The actual work is done by a recursive worker function, since that
+ ## is an easy way to traverse the tree datastructure. Here, we just check
+ ## the arguments (already done) and give over to it.
+
+ __profexplore_worker (data.FunctionTable, data.Hierarchical, "Top\n", " ");
+
+endfunction
+
+## This is the worker function. tree is the current subtree we want to
+## display / explore. parents is a string containing the already "rendered"
+## data for the parents which is displayed on top of the list of current
+## children. prefix is the prefix to add to each line rendered; this
+## is just a string of spaces to get indentation right.
+##
+## Returning 0 indicates that the user requested to totally exit the
+## explorer, thus also all higher levels should exit immediately. An integer
+## greater zero indicates to exit that many levels since the user wants to go
+## up (but not necessarily quit).
+
+function rv = __profexplore_worker (fcn_table, tree, parents, prefix)
+
+ ## Sort children by total time.
+ times = -[ tree.TotalTime ];
+ [~, p] = sort (times);
+ tree = tree(p);
+
+ while (true)
+
+ printf ("\n%s", parents);
+ strings = cell (length (tree), 1);
+ for i = 1 : length (tree)
+ strings{i} = sprintf ("%s: %d calls, %.3f total, %.3f self", ...
+ fcn_table(tree(i).Index).FunctionName, ...
+ tree(i).NumCalls, ...
+ tree(i).TotalTime, tree(i).SelfTime);
+ printf ("%s%d) %s\n", prefix, i, strings{i});
+ endfor
+ printf ("\n");
+
+ cmd = input ("profexplore> ", "s");
+ option = fix (str2double (cmd));
+
+ if (strcmp (cmd, "exit") || strcmp (cmd, "quit"))
+ rv = 0;
+ return;
+ elseif (strcmp (cmd, "help"))
+ printf ("\nCommands for profile explorer:\n\n");
+ printf ("exit Return to Octave prompt.\n");
+ printf ("quit Return to Octave prompt.\n");
+ printf ("help Display this help message.\n");
+ printf ("up [N] Go up N levels, where N is an integer. Default is 1.\n");
+ printf ("N Go down a level into option N.\n");
+ elseif (! isnan (option))
+ if (option < 1 || option > length (tree))
+ printf ("The chosen option is out of range!\n");
+ else
+ newParents = sprintf ("%s%s%s\n", parents, prefix, strings{option});
+ newPrefix = sprintf ("%s ", prefix);
+
+ rv = __profexplore_worker (fcn_table, tree(option).Children, ...
+ newParents, newPrefix);
+
+ if (rv == 0)
+ return;
+ elseif (rv > 1)
+ rv -= 1;
+ return;
+ else
+ assert (rv == 1);
+ ## It was requested to return to this level, so just stay.
+ endif
+ endif
+ elseif (length (cmd) >= 2 && strcmp (substr (cmd, 1, 2), "up"))
+ if (length (cmd) == 2)
+ rv = 1;
+ return;
+ endif
+
+ if (length (cmd) > 3 && cmd(3) == ' ')
+ opt = fix (str2double (substr (cmd, 3)));
+ if (! isnan (opt) && opt > 0)
+ rv = opt;
+ return;
+ endif
+ endif
+
+ printf ("Invalid 'up' command. Type 'help' for further");
+ printf (" information.\n");
+ else
+ printf ("Unrecognized input. Type 'help' to get a list of possible");
+ printf (" commands.\n");
+ endif
+
+ endwhile
+endfunction
+
diff -r 5e083d07ba35 -r ff4c0d97dd91 scripts/profiler/profile.m
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/profiler/profile.m Thu May 05 11:05:20 2016 +0200
@@ -0,0 +1,153 @@
+## Copyright (C) 2012-2015 Daniel Kraft
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING. If not, see
+## .
+
+## -*- texinfo -*-
+## @deftypefn {} {} profile on
+## @deftypefnx {} {} profile off
+## @deftypefnx {} {} profile resume
+## @deftypefnx {} {} profile clear
+## @deftypefnx {} address@hidden =} profile ("status")
+## @deftypefnx {} address@hidden =} profile ("info")
+## Control the built-in profiler.
+##
+## @table @code
+## @item profile on
+## Start the profiler, clearing all previously collected data if there is any.
+##
+## @item profile off
+## Stop profiling. The collected data can later be retrieved and examined
+## with @code{T = profile ("info")}.
+##
+## @item profile clear
+## Clear all collected profiler data.
+##
+## @item profile resume
+## Restart profiling without clearing the old data. All newly collected
+## statistics are added to the existing ones.
+##
+## @item @var{S} = profile ("status")
+## Return a structure with information about the current status of the
+## profiler. At the moment, the only field is @code{ProfilerStatus} which is
+## either @qcode{"on"} or @qcode{"off"}.
+##
+## @item @var{T} = profile ("info")
+## Return the collected profiling statistics in the structure @var{T}. The
+## flat profile is returned in the field @code{FunctionTable} which is an
+## array of structures, each entry corresponding to a function which was called
+## and for which profiling statistics are present. In addition, the field
+## @code{Hierarchical} contains the hierarchical call tree. Each node has an
+## index into the @code{FunctionTable} identifying the function it corresponds
+## to as well as data fields for number of calls and time spent at this level
+## in the call tree.
+## @seealso{profshow, profexplore}
+## @end table
+## @end deftypefn
+
+## Built-in profiler.
+## Author: Daniel Kraft
+
+function retval = profile (option)
+
+ if (nargin != 1)
+ print_usage ();
+ endif
+
+ switch (option)
+ case "on"
+ __profiler_reset__ ();
+ __profiler_enable__ (true);
+
+ case "off"
+ __profiler_enable__ (false);
+
+ case "clear"
+ __profiler_reset__ ();
+
+ case "resume"
+ __profiler_enable__ (true);
+
+ case "status"
+ enabled = __profiler_enable__ ();
+ if (enabled)
+ enabled = "on";
+ else
+ enabled = "off";
+ endif
+ retval = struct ("ProfilerStatus", enabled);
+
+ case "info"
+ [flat, tree] = __profiler_data__ ();
+ retval = struct ("FunctionTable", flat, "Hierarchical", tree);
+
+ otherwise
+ warning ("profile: Unrecognized option '%s'", option);
+ print_usage ();
+
+ endswitch
+
+endfunction
+
+
+%!demo
+%! profile on;
+%! A = rand (100);
+%! B = expm (A);
+%! profile off;
+%! profile resume;
+%! C = sqrtm (A);
+%! profile off;
+%! T = profile ("info");
+%! profshow (T);
+
+%!test
+%! on_struct.ProfilerStatus = "on";
+%! off_struct.ProfilerStatus = "off";
+%! profile ("on");
+%! result = logm (rand (200) + 10 * eye (200));
+%! assert (profile ("status"), on_struct);
+%! profile ("off");
+%! assert (profile ("status"), off_struct);
+%! profile ("resume");
+%! result = logm (rand (200) + 10 * eye (200));
+%! profile ("off");
+%! assert (profile ("status"), off_struct);
+%! info = profile ("info");
+%! assert (isstruct (info));
+%! assert (size (info), [1, 1]);
+%! assert (fieldnames (info), {"FunctionTable"; "Hierarchical"});
+%! ftbl = info.FunctionTable;
+%! assert (fieldnames (ftbl), {"FunctionName"; "TotalTime"; "NumCalls"; "IsRecursive"; "Parents"; "Children"});
+%! hier = info.Hierarchical;
+%! assert (fieldnames (hier), {"Index"; "SelfTime"; "TotalTime"; "NumCalls"; "Children"});
+%! profile ("clear");
+%! info = profile ("info");
+%! assert (isstruct (info));
+%! assert (size (info), [1, 1]);
+%! assert (fieldnames (info), {"FunctionTable"; "Hierarchical"});
+%! ftbl = info.FunctionTable;
+%! assert (size (ftbl), [0, 1]);
+%! assert (fieldnames (ftbl), {"FunctionName"; "TotalTime"; "NumCalls"; "IsRecursive"; "Parents"; "Children"});
+%! hier = info.Hierarchical;
+%! assert (size (hier), [0, 1]);
+%! assert (fieldnames (hier), {"Index"; "SelfTime"; "NumCalls"; "Children"});
+
+## Test input validation
+%!error profile ()
+%!error profile ("on", 2)
+%!error profile ("INVALID_OPTION")
+
diff -r 5e083d07ba35 -r ff4c0d97dd91 scripts/profiler/profshow.m
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/profiler/profshow.m Thu May 05 11:05:20 2016 +0200
@@ -0,0 +1,115 @@
+## Copyright (C) 2012-2014 Daniel Kraft
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING. If not, see
+## .
+
+## -*- texinfo -*-
+## @deftypefn {} {} profshow (@var{data})
+## @deftypefnx {} {} profshow (@var{data}, @var{n})
+## @deftypefnx {} {} profshow ()
+## @deftypefnx {} {} profshow (@var{n})
+## Display flat per-function profiler results.
+##
+## Print out profiler data (execution time, number of calls) for the most
+## critical @var{n} functions. The results are sorted in descending order by
+## the total time spent in each function. If @var{n} is unspecified it
+## defaults to 20.
+##
+## The input @var{data} is the structure returned by @code{profile ("info")}.
+## If unspecified, @code{profshow} will use the current profile dataset.
+##
+## The attribute column displays @samp{R} for recursive functions, and is blank
+## for all other function types.
+## @seealso{profexplore, profile}
+## @end deftypefn
+
+## Built-in profiler.
+## Author: Daniel Kraft
+
+function profshow (data, n = 20)
+
+ if (nargin > 2)
+ print_usage ();
+ endif
+
+ if (nargin == 0)
+ data = profile ("info");
+ elseif (nargin == 1 && ! isstruct (data))
+ n = data;
+ data = profile ("info");
+ endif
+
+ n = fix (n);
+ if (! isscalar (n) || ! isreal (n) || ! (n > 0))
+ error ("profile: N must be a positive integer");
+ endif
+
+ m = length (data.FunctionTable);
+ n = min (n, m);
+
+ ## We want to sort by times in descending order. For this, extract the
+ ## times to an array, then sort this, and use the resulting index permutation
+ ## to print out our table.
+ times = [ data.FunctionTable.TotalTime ];
+ totalTime = sum (times);
+
+ [~, p] = sort (times, "descend");
+
+ ## For printing the table, find out the maximum length of a function name
+ ## so that we can proportion the table accordingly. Based on this,
+ ## we can build the format used for printing table rows.
+ nameLen = max (length ("Function"),
+ columns (char (data.FunctionTable(p(1:n)).FunctionName)));
+ headerFormat = sprintf ("%%4s %%%ds %%4s %%12s %%10s %%12s\n", nameLen);
+ rowFormat = sprintf ("%%4d %%%ds %%4s %%12.3f %%10.2f %%12d\n", nameLen);
+
+ printf (headerFormat, ...
+ "#", "Function", "Attr", "Time (s)", "Time (%)", "Calls");
+ printf ("%s\n", repmat ("-", 1, nameLen + 2 * 5 + 11 + 2 * 13));
+
+ for i = 1 : n
+ row = data.FunctionTable(p(i));
+ timePercent = 100 * row.TotalTime / totalTime;
+ attr = "";
+ if (row.IsRecursive)
+ attr = "R";
+ endif
+ printf (rowFormat, p(i), row.FunctionName, attr,
+ row.TotalTime, timePercent, row.NumCalls);
+ endfor
+
+endfunction
+
+
+%!demo
+%! profile on;
+%! A = rand (100);
+%! B = expm (A);
+%! profile off;
+%! T = profile ("info");
+%! profshow (T, 10);
+
+%!demo
+%! profile on;
+%! expm (rand (500) + eye (500));
+%! profile off;
+%! profshow (profile ("info"), 5);
+
+%!error profshow (1, 2, 3)
+%!error profshow (struct (), ones (2))
+%!error profshow (struct (), 1+i)
+%!error profshow (struct (), -1)
+