[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.
From: |
Rik |
Subject: |
[Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch |
Date: |
Tue, 20 Aug 2019 19:00:38 -0400 (EDT) |
User-agent: |
Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko |
Follow-up Comment #30, bug #56752 (project octave):
jwe, Dan,
I looked closely at the 9 instances of the ~octave_value_list destructor being
called for the simple expression "sin (1);". I think I understand the
problematic coding pattern, but I haven't yet found a solution.
For didactic purposes, assume there is a complicated class (comp_class) which
has an extensive constructor/destructor or otherwise uses a lot of resources.
There is also a function main which uses an instance of comp_class, but the
initialization of the instance is done by a separate function init to make the
code more modular and readable.
main ()
{
comp_class cobj;
cobj = init ();
...
}
comp_class init (void)
{
comp_class retval; // local variable
retval.xxx = yyy; // initialization
...
return retval; // return by value (a comp_class object)
}
The sequence of events for the C++ runtime is
1) local variable cobj is created in main calling comp_class constructor
2) init() is called
3) local variable retval is created in main calling comp_class constructor
4) "return retval;" statement causes comp_class copy constructor to execute
copying local variable retval in to a temporary new comp_class object because
the function init returns by value.
5) init() routine completes, local variable retval goes out of scope and
comp_class destructor is called
6) back in main(), destructor for cobj is called to clear object before
assignment.
7) copy assignment operator transfers temporary comp_class object to cobj.
8) temporary value goes out of scope and calls comp_class destructor
That is a huge number of objects created/destroyed to handle what is a fairly
simple coding pattern. This example is not dreamt up, but reflects the coding
in pt-eval.cc. The function tree_evaluator::visit_index_expression is coded
like so
octave_value_list first_args;
...
first_args = convert_to_const_vector (al);
where convert_to_const_vector is declared as
octave_value_list
tree_evaluator::convert_to_const_vector (tree_argument_list *arg_list,
const octave_value *object)
One obvious solution would be to discard returning by value. In that case,
perhaps passing a reference to the octave_value_list in to the child function
so that it operates directly on the only instance we care to create. But,
this would mean changing a fair number of APIs and potentially a lot of code
refactoring.
The next most obvious thing would be to use the C++11 feature of move
constructors and move assignment operators. I added those two functions to
ovl.h along with some logging. Now when I run I get
sin(1);
octave_value_list: move constructor 893
~octave_value_list: 7772
~octave_value_list: 7773
octave_value_list: move assignment 3178
~octave_value_list: 7774
octave_value_list: move assignment 3179
~octave_value_list: 7775
octave_value_list: move assignment 3180
~octave_value_list: 7776
octave_value_1111111111list: move assignment 3181
~octave_value_list: 7777
~octave_value_list: 7778
~octave_value_list: 7779
octave_value_list: move assignment 3182
~octave_value_list: 7780
Clearly, the move routines themselves are getting called by the C++ runtime in
both flavors (constructor and assignment). However, there is no decrease in
the number of times (9) the ~octave_value_destructor is called because I
couldn't find a clean way to "zero out" the rvalue object that is being moved.
Here is the assignment routine I have at the moment:
octave_value_list& operator = (octave_value_list&& obj)
{
static long int n = 0;
std::cerr << "octave_value_list: move assignment " << ++n << std::endl;
if (this == &obj)
return *this;
std::swap (m_data, obj.m_data);
std::swap (m_names, obj.m_names);
return *this;
}
Maybe this is actually okay, but it doesn't actually result in any speed-up.
It seems to me that the octave_value class may also need to have move
functions written at the same time. An octave_value is also a "complicated
class" and there are many functions which return by value an octave_value
instance. Given that this requires creating a temporary, and the atomic
increment/decrement operators are slow, move routines in that class may be
more important.
_______________________________________________________
Reply to this item at:
<https://savannah.gnu.org/bugs/?56752>
_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, (continued)
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, Rik, 2019/08/16
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, John W. Eaton, 2019/08/16
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, Rik, 2019/08/16
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, Rik, 2019/08/16
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, John W. Eaton, 2019/08/16
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, Rik, 2019/08/16
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, Rik, 2019/08/16
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, Rik, 2019/08/16
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, John W. Eaton, 2019/08/16
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, Rik, 2019/08/17
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch,
Rik <=
- [Octave-bug-tracker] [bug #56752] Performance slowdown from version 3.2.4 through to current dev branch, John W. Eaton, 2019/08/23