After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 682277 - Multiselect of messages causes slow UI update
Multiselect of messages causes slow UI update
Status: RESOLVED FIXED
Product: evolution
Classification: Applications
Component: Mailer
3.4.x (obsolete)
Other Linux
: Normal normal
: ---
Assigned To: evolution-mail-maintainers
Evolution QA team
Depends on:
Blocks:
 
 
Reported: 2012-08-20 16:05 UTC by Milan Crha
Modified: 2013-08-20 09:26 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
initial evo patch (5.87 KB, patch)
2012-08-21 11:12 UTC, Milan Crha
needs-work Details | Review
evo patch ][ (8.61 KB, patch)
2013-08-20 09:23 UTC, Milan Crha
committed Details | Review

Description Milan Crha 2012-08-20 16:05:06 UTC
Moving this from a downstream bug report:
https://bugzilla.redhat.com/show_bug.cgi?id=849221

User claims that selecting more than 2000 messages makes behave evolution strangely, very slow update of UI when adding more messages into selection.

I'm able to reproduce this even with IMAP folders, though the user had this behaviour with EWS folder. Below is backtrace of this state, which the user gathered.

Steps to reproduce:
a) select many (2000+) messages in message list by keyboard
   (like Shift+PgUp/PgDown/ArrowUp/ArrowDown)
b) see how the response of UI gets slower and slower when adding more messages
   into selection

The window title updates count of selected messages, only message list doesn't update its content until some timeout.


Thread 1 (Thread 0xb77a78c0 (LWP 2955))

  • #0 __strcmp_ia32
    at ../sysdeps/i386/i686/strcmp.S line 45
  • #1 ews_cmp_uids
    at camel-ews-folder.c line 1696
  • #2 camel_folder_cmp_uids
    at camel-folder.c line 2538
  • #3 cmp_array_uids
    at camel-folder.c line 400
  • #4 msort_with_tmp
    at gqsort.c line 95
  • #5 msort_with_tmp
    at gqsort.c line 87
  • #6 msort_with_tmp
    at gqsort.c line 87
  • #7 msort_with_tmp
    at gqsort.c line 87
  • #8 msort_r
    at gqsort.c line 280
  • #9 g_qsort_with_data
    at gqsort.c line 305
  • #10 folder_sort_uids
    at camel-folder.c line 759
  • #11 camel_folder_sort_uids
    at camel-folder.c line 2562
  • #12 message_list_get_selected
    at message-list.c line 4207
  • #13 mail_reader_get_selected_uids
    at e-mail-reader.c line 2848
  • #14 e_mail_reader_get_selected_uids
    at e-mail-reader.c line 4235
  • #15 e_mail_shell_view_update_sidebar
    at e-mail-shell-view-private.c line 1024
  • #16 mail_shell_view_reader_changed_cb
    at e-mail-shell-view-private.c line 443
  • #17 g_cclosure_marshal_VOID__VOID
    at gmarshal.c line 85
  • #18 g_closure_invoke
    at gclosure.c line 777
  • #19 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #20 g_signal_emit_valist
    at gsignal.c line 3300
  • #21 g_signal_emit_by_name
    at gsignal.c line 3393
  • #22 reconnect_changed_event
    at e-mail-shell-content.c line 84
  • #23 g_cclosure_marshal_VOID__VOID
    at gmarshal.c line 85
  • #24 g_closure_invoke
    at gclosure.c line 777
  • #25 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #26 g_signal_emit_valist
    at gsignal.c line 3300
  • #27 g_signal_emit
    at gsignal.c line 3356
  • #28 e_mail_reader_changed
    at e-mail-reader.c line 3891
  • #29 g_cclosure_marshal_VOID__VOID
    at gmarshal.c line 85
  • #30 g_closure_invoke
    at gclosure.c line 777
  • #31 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #32 g_signal_emit_valist
    at gsignal.c line 3300
  • #33 g_signal_emit
    at gsignal.c line 3356
  • #34 et_selection_model_selection_changed
    at e-tree.c line 1087
  • #35 g_cclosure_marshal_VOID__VOID
    at gmarshal.c line 85
  • #36 g_closure_invoke
    at gclosure.c line 777
  • #37 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #38 g_signal_emit_valist
    at gsignal.c line 3300
  • #39 g_signal_emit
    at gsignal.c line 3356
  • #40 e_selection_model_selection_changed
    at e-selection-model.c line 796
  • #41 etsm_set_selection_end
    at e-tree-selection-model.c line 761
  • #42 e_selection_model_set_selection_end
    at e-selection-model.c line 486
  • #43 e_selection_model_select_as_key_press
    at e-selection-model.c line 637
  • #44 move_selection
    at e-selection-model.c line 686
  • #45 e_selection_model_key_press
    at e-selection-model.c line 715
  • #46 eti_event
    at e-table-item.c line 2769
  • #47 gnome_canvas_marshal_BOOLEAN__BOXED
    at gnome-canvas-marshal.c line 128
  • #48 g_type_class_meta_marshal
    at gclosure.c line 970
  • #49 g_closure_invoke
    at gclosure.c line 777
  • #50 signal_emit_unlocked_R
    at gsignal.c line 3589
  • #51 g_signal_emit_valist
    at gsignal.c line 3310
  • #52 g_signal_emit_by_name
    at gsignal.c line 3393
  • #53 canvas_emit_event
    at e-canvas.c line 153
  • #54 canvas_key_event
    at e-canvas.c line 533
  • #55 _gtk_marshal_BOOLEAN__BOXEDv
    at gtkmarshalers.c line 130
  • #56 g_type_class_meta_marshalv
    at gclosure.c line 997
  • #57 _g_closure_invoke_va
    at gclosure.c line 840
  • #58 g_signal_emit_valist
    at gsignal.c line 3211
  • #59 g_signal_emit
    at gsignal.c line 3356
  • #60 gtk_widget_event_internal
    at gtkwidget.c line 6380
  • #61 gtk_widget_event
    at gtkwidget.c line 6037
  • #62 gtk_window_propagate_key_event
    at gtkwindow.c line 6044
  • #63 gtk_window_key_press_event
    at gtkwindow.c line 6074
  • #64 _gtk_marshal_BOOLEAN__BOXED
    at gtkmarshalers.c line 85
  • #65 g_type_class_meta_marshal
    at gclosure.c line 970
  • #66 g_closure_invoke
    at gclosure.c line 777
  • #67 signal_emit_unlocked_R
    at gsignal.c line 3589
  • #68 g_signal_emit_valist
    at gsignal.c line 3310
  • #69 g_signal_emit
    at gsignal.c line 3356
  • #70 gtk_widget_event_internal
    at gtkwidget.c line 6380
  • #71 propagate_event
    at gtkmain.c line 2479
  • #72 gtk_main_do_event
    at gtkmain.c line 1713
  • #73 _gdk_event_emit
    at gdkevents.c line 69
  • #74 gdk_event_source_dispatch
    at gdkeventsource.c line 358
  • #75 g_main_dispatch
    at gmain.c line 2539
  • #76 g_main_context_dispatch
    at gmain.c line 3075
  • #77 g_main_context_iterate
    at gmain.c line 3146
  • #78 g_main_loop_run
    at gmain.c line 3340
  • #79 gtk_main
    at gtkmain.c line 1161
  • #80 main
    at main.c line 696

Comment 1 Milan Crha 2012-08-20 19:43:03 UTC
It's pretty easy to fix e_mail_shell_view_update_sidebar(), it calls message_list_get_selected() only for counts, but I found other issue, and that's update_actions. It's called on any change, but many unnecessary things are happening, just to be accurate. It also includes constant recreation of Labels submenu of popup menu.

I would suggest these changes for update_actions:
a) do not call it on each change in message list, not for all actions, but only
   for actions on toolbar
b) add a parameter to update-actions, something like "for-popup" or
   "force-all", which will be used to force update of all actions.
c) cache result of message_list_get_selected() in MessageList and reuse it for
   consecutive calls of that function (or message_list_selected_count())
   and update it only on selection change
d) on those "present accurate menu", like which items to enable/show based on
   message flags of the selection, or labels, set an upper limit for whose
   items to calculate it. I suggest 100 selected messages. If there are more
   messages selected then show/enable all items, same as provide Label popup
   menu items with an "unknown" state (neither checked, nor unchecked)

Matthew, does it make sense? (I do not like c) much, but that's used on too many places, all around sources, thus what one can do.)
Comment 2 Milan Crha 2012-08-20 19:44:29 UTC


Thread 1 (Thread 0x7f51599bba00 (LWP 2312))

  • #0 __strlen_sse2_pminub
    from /lib64/libc.so.6
  • #1 g_strdup
    at gstrfuncs.c line 355
  • #2 ml_getselected_cb
    at message-list.c line 4196
  • #3 foreach_path
    at e-tree-selection-model.c line 776
  • #4 g_hash_table_foreach
    at ghash.c line 1524
  • #5 e_tree_selection_model_foreach
    at e-tree-selection-model.c line 788
  • #6 e_tree_selected_path_foreach
    at e-tree.c line 1968
  • #7 message_list_get_selected
    at message-list.c line 4223
  • #8 on_selection_changed_cmd
    at message-list.c line 4063
  • #9 g_closure_invoke
    at gclosure.c line 777
  • #10 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #11 g_signal_emit_valist
    at gsignal.c line 3300
  • #12 g_signal_emit
    at gsignal.c line 3356
  • #13 et_selection_model_selection_changed
    at e-tree.c line 1087
  • #14 g_closure_invoke
    at gclosure.c line 777
  • #15 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #16 g_signal_emit_valist
    at gsignal.c line 3300
  • #17 g_signal_emit
    at gsignal.c line 3356
  • #18 e_selection_model_selection_changed
    at e-selection-model.c line 796
  • #19 etsm_set_selection_end
    at e-tree-selection-model.c line 761
  • #20 e_selection_model_set_selection_end
    at e-selection-model.c line 486

Comment 3 Milan Crha 2012-08-20 19:45:02 UTC


Thread 1 (Thread 0x7f51599bba00 (LWP 2312))

  • #0 e_tree_memory_get_type
    from /build/local/lib/evolution/3.6/libevolution-mail.so
  • #1 get_message_uid
    at message-list.c line 427
  • #2 ml_getselected_cb
    at message-list.c line 4194
  • #3 foreach_path
    at e-tree-selection-model.c line 776
  • #4 g_hash_table_foreach
    at ghash.c line 1524
  • #5 e_tree_selection_model_foreach
    at e-tree-selection-model.c line 788
  • #6 e_tree_selected_path_foreach
    at e-tree.c line 1968
  • #7 message_list_get_selected
    at message-list.c line 4223
  • #8 mail_reader_get_selected_uids
    at e-mail-reader.c line 2999
  • #9 e_mail_reader_get_selected_uids
    at e-mail-reader.c line 4477
  • #10 e_mail_reader_check_state
    at e-mail-reader.c line 4151
  • #11 mail_shell_view_update_actions
    at e-mail-shell-view.c line 859
  • #12 g_closure_invoke
    at gclosure.c line 777
  • #13 signal_emit_unlocked_R
    at gsignal.c line 3481
  • #14 g_signal_emit_valist
    at gsignal.c line 3300
  • #15 g_signal_emit
    at gsignal.c line 3356
  • #16 e_shell_view_update_actions
    at e-shell-view.c line 1767
  • #17 mail_shell_view_reader_changed_cb
    at e-mail-shell-view-private.c line 383
  • #18 g_closure_invoke
    at gclosure.c line 777
  • #19 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #20 g_signal_emit_valist
    at gsignal.c line 3300
  • #21 g_signal_emit_by_name
    at gsignal.c line 3393
  • #22 reconnect_changed_event
    at e-mail-shell-content.c line 83
  • #23 g_closure_invoke
    at gclosure.c line 777
  • #24 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #25 g_signal_emit_valist
    at gsignal.c line 3300
  • #26 g_signal_emit
    at gsignal.c line 3356
  • #27 e_mail_reader_changed
    at e-mail-reader.c line 4109
  • #28 g_closure_invoke
    at gclosure.c line 777
  • #29 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #30 g_signal_emit_valist
    at gsignal.c line 3300
  • #31 g_signal_emit
    at gsignal.c line 3356
  • #32 et_selection_model_selection_changed
    at e-tree.c line 1087
  • #33 g_closure_invoke
    at gclosure.c line 777
  • #34 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #35 g_signal_emit_valist
    at gsignal.c line 3300
  • #36 g_signal_emit
    at gsignal.c line 3356
  • #37 e_selection_model_selection_changed
    at e-selection-model.c line 796
  • #38 etsm_set_selection_end
    at e-tree-selection-model.c line 761

Comment 4 Milan Crha 2012-08-20 19:45:31 UTC


Thread 1 (Thread 0x7fd00153fa00 (LWP 31455))

  • #0 g_hash_table_lookup_node
    at ghash.c line 416
  • #1 g_hash_table_lookup
    at ghash.c line 1074
  • #2 message_info_from_uid
    at camel-folder-summary.c line 1896
  • #3 camel_folder_summary_get
    at camel-folder-summary.c line 1971
  • #4 folder_get_message_user_tag
    at camel-folder.c line 691
  • #5 camel_folder_get_message_user_tag
    at camel-folder.c line 2345
  • #6 mail_shell_view_update_label_action
    at e-mail-shell-view-actions.c line 1965
  • #7 e_mail_shell_view_update_popup_labels
    at e-mail-shell-view-actions.c line 2063
  • #8 mail_shell_view_update_actions
    at e-mail-shell-view.c line 1055
  • #9 g_closure_invoke
    at gclosure.c line 777
  • #10 signal_emit_unlocked_R
    at gsignal.c line 3481
  • #11 g_signal_emit_valist
    at gsignal.c line 3300
  • #12 g_signal_emit
    at gsignal.c line 3356
  • #13 e_shell_view_update_actions
    at e-shell-view.c line 1767
  • #14 mail_shell_view_reader_changed_cb
    at e-mail-shell-view-private.c line 383
  • #15 g_closure_invoke
    at gclosure.c line 777
  • #16 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #17 g_signal_emit_valist
    at gsignal.c line 3300
  • #18 g_signal_emit_by_name
    at gsignal.c line 3393
  • #19 reconnect_changed_event
    at e-mail-shell-content.c line 83
  • #20 g_closure_invoke
    at gclosure.c line 777
  • #21 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #22 g_signal_emit_valist
    at gsignal.c line 3300
  • #23 g_signal_emit
    at gsignal.c line 3356
  • #24 e_mail_reader_changed
    at e-mail-reader.c line 4109
  • #25 g_closure_invoke
    at gclosure.c line 777
  • #26 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #27 g_signal_emit_valist
    at gsignal.c line 3300
  • #28 g_signal_emit
    at gsignal.c line 3356
  • #29 et_selection_model_selection_changed
    at e-tree.c line 1087
  • #30 g_closure_invoke
    at gclosure.c line 777
  • #31 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #32 g_signal_emit_valist
    at gsignal.c line 3300
  • #33 g_signal_emit
    at gsignal.c line 3356
  • #34 e_selection_model_selection_changed
    at e-selection-model.c line 796
  • #35 etsm_set_selection_end
    at e-tree-selection-model.c line 761

Comment 5 Milan Crha 2012-08-20 19:45:57 UTC
Above a three more places I was able to get backtraces for.
Comment 6 Matthew Barnes 2012-08-20 22:03:59 UTC
First thing I would try is defer calling update_actions() to an idle callback, if there is not one already scheduled.  That way numerous change notifications during a single main loop iteration result in a single update_actions() call, instead of one call for each change notification.

Could even build this directly into EShellView with an e_shell_view_update_actions_in_idle() function.

Once that's done we can evaluate whether further optimizations are needed.
Comment 7 Milan Crha 2012-08-21 11:12:46 UTC
Created attachment 221979 [details] [review]
initial evo patch

for evolution;

I suppose you meant something like this. My tests showed that this doesn't help that much, evolution still uses one core when I hold Shift+PageUp to select many messages (I ended in 6000+). To be honest, the selection seems quicker here, but I know we still can do better.

One side note, about Labels submenu, if there are selected messages which some have set label and others not, then the menu shows the label name as disabled, thus user cannot set it to all selected messages. I'm pretty sure it's not what we want. If you agree, then I can file a new bug report for it.
Comment 8 Matthew Barnes 2012-08-21 11:40:39 UTC
(In reply to comment #7)
> One side note, about Labels submenu, if there are selected messages which some
> have set label and others not, then the menu shows the label name as disabled,
> thus user cannot set it to all selected messages. I'm pretty sure it's not what
> we want. If you agree, then I can file a new bug report for it.

I did that because I didn't want to show inconsistent checkmarks next to the labels.  But I suppose the checkmarks could represent a union of all labels in the selected messages.  For example if you select 4 messages with only a Red label, and 4 messages with only a Blue label, then the menu would show checkmarks next to the Red and Blue labels.
Comment 9 Matthew Barnes 2012-08-21 11:44:43 UTC
A lot of the action states really only care if 0, 1, or N > 1 messages are selected.  They don't need the full UID list or even an exact count.  If the MessageList could quickly report its selection state in terms like NONE, SINGLE or MULTIPLE that might help here.
Comment 10 André Klapper 2013-08-17 13:29:02 UTC
Comment on attachment 221979 [details] [review]
initial evo patch

$:andre\> git apply --check 682277.patch
error: patch failed: modules/mail/e-mail-shell-view-private.c:955
error: modules/mail/e-mail-shell-view-private.c: patch does not apply
error: patch failed: shell/e-shell-view.c:81
error: shell/e-shell-view.c: patch does not apply
error: patch failed: shell/e-shell-view.h:220
error: shell/e-shell-view.h: patch does not apply
Comment 11 Milan Crha 2013-08-20 09:23:19 UTC
Created attachment 252360 [details] [review]
evo patch ][

for evolution;

Updated patch. It lets me select (with Shift) 7500 messages page-by-page with responsive UI. The CPU is still high, but evolution's UI is not frozen.
Comment 12 Milan Crha 2013-08-20 09:26:14 UTC
Created commit b7e728d in evo master (3.9.91+)