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!
summary_selected returns early without calling anything when the summary view is locked, the optimisation finally looked like:
And voilà, instant-select-all in the biggest mail folders I could find.
Something things are more easy than they look like…