The rule « when it’s really slow and shouldn’t be, the cause is really simple » verifies once again. Yesterday evening, I thought I’d fix Sylpheed-Claws’ « Select All » which was really slow. It was fast on a ~100 mails folder, took 11 seconds on a 5000 mails folder, and I killed it before it finished in a 25000 mails folder. Looked exponential, so I thought gtk_clist_select_all
walked a list in the wrong way (like appending to a GSList instead of prepending). I downloaded GTK+ source and proceeded to reimplement gtk_clist_select_all
in our summary_select_all
. Sadly enough, the GTK code seemed optimized enough. No blatant O(N^2) list walking…
But looking at the gtk code, I seen gtk_clist_select_all
selects each row one by one, which has the effect of firing an tree-select-row
event. And our summary view registers such an event handler, in order to do what should be done when you select a mail. Our summary_selected
callback wasn’t buggy enough to display mails when the selection was multiple, which would have been a good reason to be slow, but it did call summary_status_show
at the beginning, in order to update the « X items selected, N kBs » label we have. Of course, to do that, summary_status_show
walks the selected list!
As summary_selected
returns early without calling anything when the summary view is locked, the optimisation finally looked like:
+ summary_lock(summaryview);
gtk_clist_select_all(GTK_CLIST(summaryview->ctree));
+ summary_unlock(summaryview);
+ summary_status_show(summaryview);
And voilà, instant-select-all in the biggest mail folders I could find.
Something things are more easy than they look like…