changeset 10033:f349847c4541

optimize cellfun (@subsref, args, {subs}, uniformoutput, true) case
author Jaroslav Hajek <highegg@gmail.com>
date Sun, 27 Dec 2009 21:56:53 +0100
parents 691b4ba32425
children 439c7a9d0fca
files src/ChangeLog src/DLD-FUNCTIONS/cellfun.cc src/ov.cc src/utils.cc src/utils.h
diffstat 5 files changed, 110 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sun Dec 27 15:18:46 2009 +0100
+++ b/src/ChangeLog	Sun Dec 27 21:56:53 2009 +0100
@@ -1,3 +1,11 @@
+2009-12-27  Jaroslav Hajek  <highegg@gmail.com>
+
+	* ov.cc (decode_subscripts): Move to utils.cc.
+	* utils.cc (decode_subscripts): New func.
+	* utils.h: Declare it.
+	* DLD-FUNCTIONS/cellfun.cc (Fcellfun): Optimize the 
+	`cellfun (@subsref, args, {subs}, "uniformoutput", true)' case.
+
 2009-12-26  Jaroslav Hajek  <highegg@gmail.com>
 
 	* gripes.cc (gripe_nonbraced_cs_list_assignment): New function.
--- a/src/DLD-FUNCTIONS/cellfun.cc	Sun Dec 27 15:18:46 2009 +0100
+++ b/src/DLD-FUNCTIONS/cellfun.cc	Sun Dec 27 21:56:53 2009 +0100
@@ -380,6 +380,32 @@
           else
             error ("not enough arguments for `isclass'");
         }
+      else if (name == "subsref" && nargin == 5 && nargout == 1
+               && args(2).numel () == 1 && args(2).is_cell () 
+               && args(3).is_string ()
+               && args(3).xtoupper ().string_value () == "uniformoutput"
+               && args(4).bool_value () && ! error_state)
+        {
+          // This optimizes the case of applying the same index expression to
+          // multiple values. We decode the subscript just once. uniformoutput must
+          // be requested as well.
+
+          const Cell tmpc = args(2).cell_value ();
+          octave_value subs = tmpc(0);
+
+          std::string type;
+          std::list<octave_value_list> idx;
+          decode_subscripts ("subsref", subs, type, idx);
+
+          if (! error_state)
+            {
+              Cell result (f_args.dims ());
+              for (octave_idx_type count = 0; count < k && ! error_state; count++)
+                result(count) = f_args.elem (count).subsref (type, idx);
+
+              retval(0) = result;
+            }
+        }
       else
         {
           if (! valid_identifier (name))
--- a/src/ov.cc	Sun Dec 27 15:18:46 2009 +0100
+++ b/src/ov.cc	Sun Dec 27 21:56:53 2009 +0100
@@ -2700,77 +2700,6 @@
   return retval;
 }
 
-static void
-decode_subscripts (const char* name, const octave_value& arg,
-		   std::string& type_string,
-		   std::list<octave_value_list>& idx)
-{
-  Octave_map m = arg.map_value ();
-
-  if (! error_state
-      && m.nfields () == 2 && m.contains ("type") && m.contains ("subs"))
-    {
-      Cell& type = m.contents ("type");
-      Cell& subs = m.contents ("subs");
-
-      type_string = std::string (type.length(), '\0');
-
-      for (int k = 0; k < type.length (); k++)
-	{
-	  std::string item = type(k).string_value ();
-
-	  if (! error_state)
-	    {
-	      if (item == "{}")
-		type_string[k] = '{';
-	      else if (item == "()")
-		type_string[k] = '(';
-	      else if (item == ".")
-		type_string[k] = '.';
-	      else
-		{
-		  error("%s: invalid indexing type `%s'", name, item.c_str ());
-		  return;
-		}
-	    }
-	  else
-	    {
-	      error ("%s: expecting type(%d) to be a character string",
-		     name, k+1);
-	      return;
-	    }
-
-	  octave_value_list idx_item;
-
-	  if (subs(k).is_string ())
-	    idx_item(0) = subs(k);
-	  else if (subs(k).is_cell ())
-	    {
-	      Cell subs_cell = subs(k).cell_value ();
-
-	      for (int n = 0; n < subs_cell.length (); n++)
-		{
-		  if (subs_cell(n).is_string ()
-		      && subs_cell(n).string_value () == ":")
-		    idx_item(n) = octave_value(octave_value::magic_colon_t);
-		  else
-		    idx_item(n) = subs_cell(n);
-		}
-	    }
-	  else
-	    {
-	      error ("%s: expecting subs(%d) to be a character string or cell array",
-		     name, k+1);
-	      return;
-	    }
-
-	  idx.push_back (idx_item);
-	}
-    }
-  else
-    error ("%s: second argument must be a structure with fields `type' and `subs'", name);
-}
-
 DEFUN (subsref, args, nargout,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} subsref (@var{val}, @var{idx})\n\
--- a/src/utils.cc	Sun Dec 27 15:18:46 2009 +0100
+++ b/src/utils.cc	Sun Dec 27 21:56:53 2009 +0100
@@ -1045,6 +1045,77 @@
   return retval;
 }
 
+void
+decode_subscripts (const char* name, const octave_value& arg,
+		   std::string& type_string,
+		   std::list<octave_value_list>& idx)
+{
+  Octave_map m = arg.map_value ();
+
+  if (! error_state
+      && m.nfields () == 2 && m.contains ("type") && m.contains ("subs"))
+    {
+      Cell& type = m.contents ("type");
+      Cell& subs = m.contents ("subs");
+
+      type_string = std::string (type.length(), '\0');
+
+      for (int k = 0; k < type.length (); k++)
+	{
+	  std::string item = type(k).string_value ();
+
+	  if (! error_state)
+	    {
+	      if (item == "{}")
+		type_string[k] = '{';
+	      else if (item == "()")
+		type_string[k] = '(';
+	      else if (item == ".")
+		type_string[k] = '.';
+	      else
+		{
+		  error("%s: invalid indexing type `%s'", name, item.c_str ());
+		  return;
+		}
+	    }
+	  else
+	    {
+	      error ("%s: expecting type(%d) to be a character string",
+		     name, k+1);
+	      return;
+	    }
+
+	  octave_value_list idx_item;
+
+	  if (subs(k).is_string ())
+	    idx_item(0) = subs(k);
+	  else if (subs(k).is_cell ())
+	    {
+	      Cell subs_cell = subs(k).cell_value ();
+
+	      for (int n = 0; n < subs_cell.length (); n++)
+		{
+		  if (subs_cell(n).is_string ()
+		      && subs_cell(n).string_value () == ":")
+		    idx_item(n) = octave_value(octave_value::magic_colon_t);
+		  else
+		    idx_item(n) = subs_cell(n);
+		}
+	    }
+	  else
+	    {
+	      error ("%s: expecting subs(%d) to be a character string or cell array",
+		     name, k+1);
+	      return;
+	    }
+
+	  idx.push_back (idx_item);
+	}
+    }
+  else
+    error ("%s: second argument must be a structure with fields `type' and `subs'", name);
+}
+
 Matrix
 identity_matrix (octave_idx_type nr, octave_idx_type nc)
 {
--- a/src/utils.h	Sun Dec 27 15:18:46 2009 +0100
+++ b/src/utils.h	Sun Dec 27 21:56:53 2009 +0100
@@ -28,6 +28,7 @@
 
 #include <iosfwd>
 #include <string>
+#include <list>
 
 #include "dMatrix.h"
 #include "lo-utils.h"
@@ -95,7 +96,10 @@
 extern OCTINTERP_API octave_idx_type
 dims_to_numel (const dim_vector& dims, const octave_value_list& idx);
 
-
+extern OCTINTERP_API void
+decode_subscripts (const char* name, const octave_value& arg,
+		   std::string& type_string,
+		   std::list<octave_value_list>& idx);
 
 extern OCTINTERP_API Matrix
 identity_matrix (octave_idx_type nr, octave_idx_type nc);