changeset 10408:a8869743d9fe

optimize strchr
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 11 Mar 2010 10:15:52 +0100
parents 2516ca5763e9
children a87afd063e7d
files scripts/ChangeLog scripts/strings/strchr.m
diffstat 2 files changed, 23 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Tue Mar 09 08:10:05 2010 +0100
+++ b/scripts/ChangeLog	Thu Mar 11 10:15:52 2010 +0100
@@ -1,3 +1,7 @@
+2010-03-11  Jaroslav Hajek  <highegg@gmail.com>
+
+	* strings/strchr.m: Optimize.
+
 2010-03-05  Soren Hauberg  <hauberg@gmail.com>
 
 	* pkg/pkg.m (write_index): include classes in autogenerated INDEX files.
--- a/scripts/strings/strchr.m	Tue Mar 09 08:10:05 2010 +0100
+++ b/scripts/strings/strchr.m	Thu Mar 11 10:15:52 2010 +0100
@@ -33,11 +33,27 @@
   if (nargin < 2 || ! ischar (str) || ! ischar (chars))
     print_usage ();
   endif
-  f = false (1, 256);
-  f(chars + 1) = true;
+  if (isempty (chars))
+    mask = false (size (str));
+  elseif (length (chars) <= 6)
+    ## With a few characters, it pays off to build the mask incrementally.
+    ## We do it via a for loop to save memory.
+    mask = str == chars(1);
+    for i = 2:length (chars)
+      mask |= str == chars(i);
+    endfor
+  else
+    ## Index the str into a mask of valid values. This is slower than it could be
+    ## because of the +1 issue.
+    f = false (1, 256);
+    f(chars + 1) = true;
+    si = uint32 (str); # default goes via double - unnecessarily long.
+    ++si; # in-place
+    mask = reshape (f(si), size (str));
+  endif
   varargout = cell (1, nargout);
   varargout{1} = [];
-  [varargout{:}] = find (reshape (f(str + 1), size (str)), varargin{:});
+  [varargout{:}] = find (mask, varargin{:});
 endfunction 
 
 %!assert(strchr("Octave is the best software","best"),[3, 6, 9, 11, 13, 15, 16, 17, 18, 20, 23, 27])