# HG changeset patch # User Jaroslav Hajek # Date 1231680472 -3600 # Node ID c1709a45b45be1b25ab5bcea9c7ee8f1a04c876b # Parent fd11a08a9b31635c352b86a79964563321771760 optimize structure components access diff -r fd11a08a9b31 -r c1709a45b45b src/ChangeLog --- a/src/ChangeLog Sun Jan 11 07:55:44 2009 +0100 +++ b/src/ChangeLog Sun Jan 11 14:27:52 2009 +0100 @@ -1,3 +1,10 @@ +2009-01-11 Jaroslav Hajek + + * ov.h (octave_value::is_copy_of): New method. + * ov-struct.cc (numeric_conv): Add output parameter orig. + (octave_struct::subsasgn): Temporarily erase duplicate lhs value prior + to assignment. + 2009-01-11 Jaroslav Hajek * oct-obj.cc (octave_value_list::all_scalars): New method. diff -r fd11a08a9b31 -r c1709a45b45b src/ov-struct.cc --- a/src/ov-struct.cc Sun Jan 11 07:55:44 2009 +0100 +++ b/src/ov-struct.cc Sun Jan 11 14:27:52 2009 +0100 @@ -224,11 +224,26 @@ u = octave_value::empty_conv (type.substr (2), rhs); else { - Cell map_val = map.contents (key); + Cell& cell_ref = map.contents (key); + + octave_value u1 = cell_ref.index (idx.front (), true); + u = numeric_conv (u1, type.substr (2)); - Cell map_elt = map_val.index (idx.front (), true); + if (u.is_defined () && u.is_copy_of (u1)) + { + // This is a bit of black magic. u is a shallow copy + // of an element inside this struct, and maybe more. To + // prevent make_unique from always forcing a copy, we + // temporarily delete the stored value. + u1 = octave_value (); + cell_ref.assign (idx.front (), Cell (octave_value ())); + u.make_unique (); + cell_ref.assign (idx.front (), Cell (u)); + } + else + // Safe is safe. + u.make_unique (); - u = numeric_conv (map_elt, type.substr (2)); } if (! error_state) @@ -241,8 +256,6 @@ next_idx.erase (next_idx.begin ()); next_idx.erase (next_idx.begin ()); - u.make_unique (); - t_rhs = u.subsasgn (type.substr (2), next_idx, rhs); } } @@ -265,9 +278,23 @@ u = octave_value::empty_conv (type.substr (1), rhs); else { - Cell map_val = map.contents (key); + Cell& cell_ref = map.contents (key); + + u = numeric_conv (cell_ref, type.substr (2)); - u = numeric_conv (map_val, type.substr (1)); + if (u.is_defined () && u.is_copy_of (cell_ref(0))) + { + // This is a bit of black magic. u is a shallow copy + // of an element inside this struct, and maybe more. To + // prevent make_unique from always forcing a copy, we + // temporarily delete the stored value. + cell_ref(0) = octave_value (); + u.make_unique (); + cell_ref(0) = u; + } + else + // Safe is safe. + u.make_unique (); } if (! error_state) @@ -276,8 +303,6 @@ next_idx.erase (next_idx.begin ()); - u.make_unique (); - t_rhs = u.subsasgn (type.substr (1), next_idx, rhs); } } diff -r fd11a08a9b31 -r c1709a45b45b src/ov.h --- a/src/ov.h Sun Jan 11 07:55:44 2009 +0100 +++ b/src/ov.h Sun Jan 11 14:27:52 2009 +0100 @@ -915,6 +915,8 @@ const octave_base_value& get_rep (void) const { return *rep; } + bool is_copy_of (const octave_value &val) const { return rep == val.rep; } + void print_info (std::ostream& os, const std::string& prefix = std::string ()) const;