Re: Dispatch of GObject virtual functions in GtkMM



On 1/28/07, Daniel Elstner <daniel kitta googlemail com> wrote:
Am Sonntag, den 28.01.2007, 12:43 -0600 schrieb Matt Hoosier:

> Yeah, agreed. These are all non-custom widgets, so the
> Glib::ObjectBase() constructor should be called with the 0 parameter
> to indicate no fancy dispatch needs to happen.

Right.

> Maybe there's just so little actual work (usually, plop the child
> widget inside a linked list and mark a size-negotiation queue request)
> that the C++ call itself is a big fraction of the total execution.

Yes, this could be.  Some type conversions can be rather expensive, as
e.g. objects of boxed type have to be copied in order to put them into
the wrapper object, which involves memory allocation.  Even if no type
conversion takes place, retrieving the wrapper instance from the GObject
requires at least one hash table lookup.  reference() and unreference()
are also a bit more expensive than they should be, since both are
virtual (pointlessly so, in my opinion) and might even involve locking
or atomic increment/decrement on the GObject side.

> On the other hand, for custom widgets: perhaps there's some way that
> custom widgets can override the vfunc pointer in their GObject class
> in exactly the same way that one does when overriding a method in
> regular GObject? Would that break anything in gtkmm?

Well, if you subclass the GObject as you would in plain C without gtkmm,
it's of course possible to wrap the result as a non-custom widget in
gtkmm.  Is that what you meant?

Not quite. I had something more like this in mind:

   class CustomWidget : public Gtk::Widget
   {
       private:
           static gboolean
           expose_event (GtkWidget* w, GdkEventExpose* e)
           {
               // custom handling
               ...
               // end custom handling

               GtkWidgetClass* klass = < look up base class's
GtkWidgetClass instance >;
               return klass->expose_event (w, e);
           }

       public:
           CustomWidget ()
           {
               static bool lazy_init_done = false;

               if (!lazy_init_done)
               {
                   GtkWidgetClass* klass = < macros to fetch class
object for this new GType > ;
                   klass->expose_event = CustomWidget::expose_event;
                   lazy_init_done = true;
               }
           }
   };


> > Also, are you using code size optimization, which could make it slower?
> > Are you building with exceptions?
>
> Yes, I'm using -Os; exceptions are disabled.

As a side note, I discovered that at least with GCC 4.1, -O3 actually
produces smaller binaries than -O2 for my C++ programs on the amd64
architecture.  This is probably in part due to automatic inlining of
very small functions like Gtk::manage<>(), which would otherwise be
replicated with identical content for each different template argument
used.

In my opinion functions like Gtk::manage<>() should have been declared
inline in the first place, but unfortunately we can't do that now
without breaking ABI.  (Well, unless one uses some trickery to always
include the definition of the inline function when compiling the library
itself, but...)

On another unrelated side note, the way GCC implements exception
handling there is absolutely no overhead in the generated code if no
exception is actually thrown.  Apart from the code size increase, of
course.  The exception handling paths are appended at the bottom of the
function.

--Daniel






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]