[gtk/wip/chergert/reduce-action-muxer-allocations] menutracker: reduce allocations and signal emission
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/reduce-action-muxer-allocations] menutracker: reduce allocations and signal emission
- Date: Wed, 8 Dec 2021 06:42:31 +0000 (UTC)
commit 00d5f72d6ea125cd64013c1770d38cd083d0c8f8
Author: Christian Hergert <chergert redhat com>
Date: Tue Dec 7 22:33:20 2021 -0800
menutracker: reduce allocations and signal emission
When handling action-added callbacks the code was previously using a
freeze_notify/thaw_notify in all cases. This turns out to allocate a
significant amount of memory when called a lot.
That said, it shouldn't be getting called this much but given the current
state of affairs elsewhere in GtkActionMuxer, this brought temporary
allocations down from 9MiB to 9KiB in gnome-text-editor after showing
the context menu a few times.
Related #4422
gtk/gtkmenutrackeritem.c | 31 +++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)
---
diff --git a/gtk/gtkmenutrackeritem.c b/gtk/gtkmenutrackeritem.c
index 70ac0de8aa..9a9732e28a 100644
--- a/gtk/gtkmenutrackeritem.c
+++ b/gtk/gtkmenutrackeritem.c
@@ -286,7 +286,7 @@ gtk_menu_tracker_item_update_visibility (GtkMenuTrackerItem *self)
if (visible != self->is_visible)
{
self->is_visible = visible;
- g_object_notify (G_OBJECT (self), "is-visible");
+ g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_IS_VISIBLE]);
}
}
@@ -300,9 +300,17 @@ gtk_menu_tracker_item_action_added (GtkActionObserver *observer,
{
GtkMenuTrackerItem *self = GTK_MENU_TRACKER_ITEM (observer);
GVariant *action_target;
+ gboolean old_sensitive;
+ gboolean old_toggled;
+ GtkMenuTrackerItemRole old_role;
+ guint n_changed;
GTK_NOTE(ACTIONS, g_message ("menutracker: action %s added", action_name));
+ old_sensitive = self->sensitive;
+ old_toggled = self->toggled;
+ old_role = self->role;
+
action_target = g_menu_item_get_attribute_value (self->item, G_MENU_ATTRIBUTE_TARGET, NULL);
self->can_activate = (action_target == NULL && parameter_type == NULL) ||
@@ -340,18 +348,29 @@ gtk_menu_tracker_item_action_added (GtkActionObserver *observer,
self->role = GTK_MENU_TRACKER_ITEM_ROLE_CHECK;
}
- g_object_freeze_notify (G_OBJECT (self));
+ /* Avoid freeze/thaw_notify as they are quite expensive in runtime/memory
+ * unless we have more than one property to update. Additionally, only
+ * notify on properties that have changed to avoid extraneous signal
+ * emission. This code can get run a lot!
+ */
+ n_changed = (old_role != self->role)
+ + (old_toggled != self->toggled)
+ + (old_sensitive != self->sensitive);
+
+ if (n_changed > 1)
+ g_object_freeze_notify (G_OBJECT (self));
- if (self->sensitive)
+ if (self->sensitive != old_sensitive)
g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_SENSITIVE]);
- if (self->toggled)
+ if (self->toggled != old_toggled)
g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_TOGGLED]);
- if (self->role != GTK_MENU_TRACKER_ITEM_ROLE_NORMAL)
+ if (self->role != old_role)
g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_ROLE]);
- g_object_thaw_notify (G_OBJECT (self));
+ if (n_changed > 1)
+ g_object_thaw_notify (G_OBJECT (self));
if (action_target)
g_variant_unref (action_target);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]