GNOME Bugzilla – Bug 153613
GtkTreeView slow with long lists
Last modified: 2018-02-10 04:33:31 UTC
The following short program creates a GtkListStore/GtkTreeView with seven columns. The columns are set with fixed sizing and a minimum size of 40 pixels. This is placed in a 400x400 window along with a button. The list is initially populated with 512 rows. Clicking the button does the following: 1. Measures the time it takes to call gtk_list_store_clear. 2. Measures the time it takes to fill the list with twice as many rows using gtk_list_store_append/gtk_list_store_set. 3. Measures the time it takes to process all outstanding events. On my machine (P3-733, GTK+ 2.4.9) I get the following results: Clearing 512 elements took 25447 usec (0.03 seconds). Adding 1024 elements took 78359 usec (0.08 seconds). Event loop took 917066 usec (0.92 seconds). Clearing 1024 elements took 46791 usec (0.05 seconds). Adding 2048 elements took 149946 usec (0.15 seconds). Event loop took 1781791 usec (1.78 seconds). Clearing 2048 elements took 94762 usec (0.09 seconds). Adding 4096 elements took 297461 usec (0.30 seconds). Event loop took 3449965 usec (3.45 seconds). Clearing 4096 elements took 189300 usec (0.19 seconds). Adding 8192 elements took 604548 usec (0.60 seconds). Event loop took 6816845 usec (6.82 seconds). During the time the event loop is running, the button appears depressed (the application is hung). All of the times seem excessive, especially given that the columns are each of a fixed size. Even a list of only 1024 elements is already taking over a second to deal with. Larger lists get very slow to deal with.
Created attachment 31893 [details] Test application
Was this measured with 2.4 or HEAD ? HEAD has a new list store implementation and should scale better.
The measurements above are from GTK+ 2.4.9. Using the latest from HEAD, there seems to be no significant speed improvement for this test. Here are the results from HEAD (again, P3-733): Adding 512 elements took 31876 usec (31.88 ms). Event loop took 456 usec (0.46 ms). --- click 1 Clearing 512 elements took 25706 usec (25.71 ms). Adding 1024 elements took 78939 usec (78.94 ms). Event loop took 830231 usec (830.23 ms). --- click 2 Clearing 1024 elements took 47323 usec (47.32 ms). Adding 2048 elements took 153779 usec (153.78 ms). Event loop took 1618278 usec (1618.28 ms). --- click 3 Clearing 2048 elements took 98752 usec (98.75 ms). Adding 4096 elements took 308651 usec (308.65 ms). Event loop took 3172603 usec (3172.60 ms). --- click 4 Clearing 4096 elements took 194741 usec (194.74 ms). Adding 8192 elements took 624880 usec (624.88 ms). Event loop took 6313566 usec (6313.57 ms). --- click 5 Clearing 8192 elements took 394690 usec (394.69 ms). Adding 16384 elements took 1250056 usec (1250.06 ms). Event loop took 12618901 usec (12618.90 ms).
Created attachment 31936 [details] Noninteractive test application Here is the non-interactive version which is more useful for profiling.
I'm not surprised that clear() is slow. It removes each row individually, as there is no interface for adding/removing multiple items in a GtkTreeModel. A much better way to achieve the same effect is to remove the model and add a fresh one. I'm tempted to close this WONTFIX, as 1) there's a workaround available, and 2) It'll be really hard to fix. It might be nice to update the docs to mention that ::clear() is slow, and that readding a new model might be faster.
Thanks, switching to a new model works to remove the cost of clearing the list, but the time spent creating the model and the work in the event loop remains the same.
Using "fixed-height-mode" on the GtkTreeView helps a lot. Here are my results using GTK+ 2.4.9 and setting the fixed-height-mode property: Adding 512 elements took 29020 usec (29.02 ms). Event loop took 882 usec (0.88 ms). --- click 1 Clearing 512 elements took 21330 usec (21.33 ms). Adding 1024 elements took 95761 usec (95.76 ms). Event loop took 111473 usec (111.47 ms). --- click 2 Clearing 1024 elements took 44922 usec (44.92 ms). Adding 2048 elements took 188845 usec (188.84 ms). Event loop took 118530 usec (118.53 ms). --- click 3 Clearing 2048 elements took 91306 usec (91.31 ms). Adding 4096 elements took 381963 usec (381.96 ms). Event loop took 112236 usec (112.24 ms). --- click 4 Clearing 4096 elements took 181237 usec (181.24 ms). Adding 8192 elements took 761145 usec (761.14 ms). Event loop took 113022 usec (113.02 ms). --- click 5 Clearing 8192 elements took 373268 usec (373.27 ms). Adding 16384 elements took 1531376 usec (1531.38 ms). Event loop took 112127 usec (112.13 ms). This is starting to look more reasonable, although it is interesting that my numbers for adding elements to the list store seem to consistently increase in fixed height mode.
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue for it.