Optimisations

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…