changeset 10760:76079e505f9d

optimize cellfun with uniform struct output
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 01 Jul 2010 08:51:14 +0200
parents d9e57045b9e1
children 12dfe91e9fab
files src/ChangeLog src/oct-map.cc src/oct-map.h src/ov-struct.cc src/ov-struct.h
diffstat 5 files changed, 124 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
+2010-07-01  Jaroslav Hajek  <highegg@gmail.com>
+
+	* oct-map.cc (octave_fields::equal_up_to_order (const octave_fields&,
+	octave_idx_type *)): New overload.
+	(octave_fields::equal_up_to_order (const octave_fields&,
+	Array<octave_idx_type>&)): Use it here.
+	(octave_map::fast_elem_insert,
+	octave_map::fast_elem_extract): New methods.
+	* oct-map.h: Update decls.
+	* ov-struct.cc (octave_struct::fast_elem_extract,
+	octave_struct::fast_elem_insert,
+	octave_scalar_struct::fast_elem_insert_self): New methods.
+	* ov-struct.h: Update decls.
+
 2010-06-28  Jaroslav Hajek  <highegg@gmail.com>
 
 	* data.cc (single_type_concat): Optimize all scalars case where
--- a/src/oct-map.cc
+++ b/src/oct-map.cc
@@ -108,21 +108,17 @@
 
 bool 
 octave_fields::equal_up_to_order (const octave_fields& other,
-                                  Array<octave_idx_type>& perm) const
+                                  octave_idx_type* perm) const
 {
   bool retval = true;
 
   octave_idx_type n = nfields ();
-  if (perm.length () != n)
-    perm.clear (1, n);
-  else
-    perm.make_unique (); // optimization
 
   iterator p = begin (), q = other.begin ();
   for (; p != end () && q != other.end (); p++, q++)
     {
       if (p->first == q->first)
-        perm.xelem(p->second) = q->second;
+        perm[p->second] = q->second;
       else
         {
           retval = false;
@@ -135,6 +131,19 @@
   return retval;
 }
 
+bool 
+octave_fields::equal_up_to_order (const octave_fields& other,
+                                  Array<octave_idx_type>& perm) const
+{
+  bool retval = true;
+
+  octave_idx_type n = nfields ();
+  if (perm.length () != n)
+    perm.clear (1, n);
+
+  return equal_up_to_order (other, perm.fortran_vec ());
+}
+
 string_vector
 octave_fields::fieldnames (void) const
 {
@@ -382,6 +391,45 @@
   return retval;
 }
 
+octave_scalar_map
+octave_map::fast_elem_extract (octave_idx_type n) const
+{
+  octave_scalar_map retval (xkeys);
+
+  extract_scalar (retval, n);
+
+  return retval;
+}
+
+bool
+octave_map::fast_elem_insert (octave_idx_type n, 
+                              const octave_scalar_map& rhs)
+{
+  bool retval = false;
+
+  octave_idx_type nf = nfields ();
+  if (rhs.xkeys.is_same (xkeys))
+    {
+      for (octave_idx_type i = 0; i < nf; i++)
+        xvals[i](n) = rhs.xvals[i];
+
+      retval = true;
+    }
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, perm, nf);
+      if (xkeys.equal_up_to_order (rhs.xkeys, perm))
+        {
+          for (octave_idx_type i = 0; i < nf; i++)
+            xvals[i](n) = rhs.xvals[perm[i]];
+
+          retval = true;
+        }
+    }
+
+  return retval;
+}
+
 octave_map
 octave_map::squeeze (void) const
 {
--- a/src/oct-map.h
+++ b/src/oct-map.h
@@ -124,6 +124,9 @@
   // returns a permutation needed to bring the fields of *other*
   // into the order of *this*.
   bool equal_up_to_order (const octave_fields& other,
+                          octave_idx_type* perm) const;
+
+  bool equal_up_to_order (const octave_fields& other,
                           Array<octave_idx_type>& perm) const;
 
   bool is_same (const octave_fields& other) const
@@ -432,6 +435,12 @@
 
   octave_map concat (const octave_map& rb, const Array<octave_idx_type>& ra_idx);
 
+  // like checkelem, but no check.
+  octave_scalar_map fast_elem_extract (octave_idx_type n) const;
+
+  // element assignment, no bounds check
+  bool fast_elem_insert (octave_idx_type n, const octave_scalar_map& rhs);
+
 private:
 
   octave_fields xkeys;
--- a/src/ov-struct.cc
+++ b/src/ov-struct.cc
@@ -1074,6 +1074,33 @@
   return retval;
 }
 
+octave_value
+octave_struct::fast_elem_extract (octave_idx_type n) const
+{
+  if (n < map.numel ())
+    return map.checkelem (n);
+  else
+    return octave_value ();
+}
+
+bool
+octave_struct::fast_elem_insert (octave_idx_type n, 
+                                 const octave_value& x)
+{
+  bool retval = false;
+
+  if (n < map.numel ())
+    {
+      // To avoid copying the scalar struct, it just stores a pointer to
+      // itself.
+      const octave_scalar_map *sm_ptr;
+      void *here = reinterpret_cast<void *>(&sm_ptr);
+      return (x.get_rep().fast_elem_insert_self (here, btyp_struct)
+              && map.fast_elem_insert (n, *sm_ptr));
+    }
+
+  return retval;
+}
 DEFINE_OCTAVE_ALLOCATOR(octave_scalar_struct);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_scalar_struct, "scalar struct", "struct");
@@ -1682,6 +1709,18 @@
   return new octave_struct (octave_map (map));
 }
 
+bool
+octave_scalar_struct::fast_elem_insert_self (void *where, builtin_type_t btyp) const
+{
+
+  if (btyp == btyp_struct)
+    {
+      *(reinterpret_cast<const octave_scalar_map **>(where)) = &map;
+      return true;
+    }
+  else
+    return false;
+}
 /*
 %!shared x
 %! x(1).a=1; x(2).a=2; x(1).b=3; x(2).b=3;
--- a/src/ov-struct.h
+++ b/src/ov-struct.h
@@ -153,6 +153,12 @@
 
   mxArray *as_mxArray (void) const;
 
+  octave_value
+  fast_elem_extract (octave_idx_type n) const;
+
+  bool
+  fast_elem_insert (octave_idx_type n, const octave_value& x);
+
 protected:
 
   // The associative array used to manage the structure data.
@@ -268,6 +274,8 @@
 
   mxArray *as_mxArray (void) const;
 
+  bool fast_elem_insert_self (void *where, builtin_type_t btyp) const;
+
 protected:
 
   // The associative array used to manage the structure data.