# HG changeset patch # User Jaroslav Hajek # Date 1277967074 -7200 # Node ID 76079e505f9d7d26d71d24f59115c3b098f2c107 # Parent d9e57045b9e19d354cc4a272434e73dcc0069df6 optimize cellfun with uniform struct output diff -r d9e57045b9e1 -r 76079e505f9d src/ChangeLog --- a/src/ChangeLog Tue Jun 29 09:05:19 2010 +0200 +++ b/src/ChangeLog Thu Jul 01 08:51:14 2010 +0200 @@ -1,3 +1,17 @@ +2010-07-01 Jaroslav Hajek + + * 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&)): 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 * data.cc (single_type_concat): Optimize all scalars case where diff -r d9e57045b9e1 -r 76079e505f9d src/oct-map.cc --- a/src/oct-map.cc Tue Jun 29 09:05:19 2010 +0200 +++ b/src/oct-map.cc Thu Jul 01 08:51:14 2010 +0200 @@ -108,21 +108,17 @@ bool octave_fields::equal_up_to_order (const octave_fields& other, - Array& 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& 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 { diff -r d9e57045b9e1 -r 76079e505f9d src/oct-map.h --- a/src/oct-map.h Tue Jun 29 09:05:19 2010 +0200 +++ b/src/oct-map.h Thu Jul 01 08:51:14 2010 +0200 @@ -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& perm) const; bool is_same (const octave_fields& other) const @@ -432,6 +435,12 @@ octave_map concat (const octave_map& rb, const Array& 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; diff -r d9e57045b9e1 -r 76079e505f9d src/ov-struct.cc --- a/src/ov-struct.cc Tue Jun 29 09:05:19 2010 +0200 +++ b/src/ov-struct.cc Thu Jul 01 08:51:14 2010 +0200 @@ -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(&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(where)) = ↦ + return true; + } + else + return false; +} /* %!shared x %! x(1).a=1; x(2).a=2; x(1).b=3; x(2).b=3; diff -r d9e57045b9e1 -r 76079e505f9d src/ov-struct.h --- a/src/ov-struct.h Tue Jun 29 09:05:19 2010 +0200 +++ b/src/ov-struct.h Thu Jul 01 08:51:14 2010 +0200 @@ -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.