-
Notifications
You must be signed in to change notification settings - Fork 187
Speed up TreeItem.getItemCount() and TreeItem.getItemCount() #882 #883
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…pse-platform#882 On Linux these methods have linear complexity over child count, that causes quadratic complexity for virtual tree navigation.
…pse-platform#882 On Linux these methods have linear complexity over child count, that causes quadratic complexity for virtual tree navigation.
Add cache invalidation only to obvious places for now.
|
I've implemented a straightforward caching of item count. It helps in static gboolean
gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *parent,
gint n)
{
GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
GtkTreeStorePrivate *priv = tree_store->priv;
GNode *parent_node;
GNode *child;
g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
if (parent == NULL)
parent_node = priv->root;
else
parent_node = parent->user_data;
child = g_node_nth_child (parent_node, n);
if (child)
{
iter->user_data = child;
iter->stamp = priv->stamp;
return TRUE;
}
else
{
iter->stamp = 0;
return FALSE;
}
}g_node_nth_child is linear: GNode*
g_node_nth_child (GNode *node,
guint n)
{
g_return_val_if_fail (node != NULL, NULL);
node = node->children;
if (node)
while ((n-- > 0) && node)
node = node->next;
return node;
}So at best I've reduced time in Jface case of interest by half, not by a thousand times. UPDATE: UPDATE 2: |
TreeItem.getItem(int) had linear complexity, full traversal had quadratic complexity. To alleviate this, we cache the result. Note: this only speeds up breadth-first traversal as cache operates on "item of interest" basis, dropping contents if another item is requested.
datasets eclipse-platform#882 Test_org_eclipse_swt_widgets_Tree.test_getItemNoGrowth() was failing for virtual trees.
|
The immediate problem is solved, but in a strange way. There is a suggestion to abolish GTK queires for children entirely and track parent-child relationship in Java code like MacOS implementation does. I'm not ready to work on that, as scope is much greater, so I publish my current hackish solution for review and discussion. |
…-platform#882 As assertion now works with a time require for a single operation, we can't assume that non-constant operation will not fit in 100 ns window.
Tests have been modified to use time limits instead of fixed iteration count. Now each test takes 7-14 seconds on Mac OS.
Any algorithm would be fast on a binary tree due to low count of items in each node. We need a wide tree to break traversal tests.
Wide tree traversal shows performance 4 times worse than optimal on wide trees.
Breadth first traversal is somewhat similar lazy TreeViewer from JFace does on reveal - it populates a whole level of a tree, then select an item and goes down a level.
|
Sorry, I've forgot to test the JFace reveal test from eclipse-platform/eclipse.platform.ui#649 Back to draft. |
|
JFace reveal is still quadratic: My tests probably do not adequately represent JFace interaction with Tree. |
|
I give up for now. |
This alleviates #882, by caching results of heavy operations.
On Linux, methods
TreeItem.getItemCount()andTreeItem.getItem(int)take time proportional to child count (have linear asymptotic complexity). This causes quadratic execution time in JFaceTreeViewer.reveal()method, which uses these to eagerly populate expanded virtual Tree nodes.This PR demonstrates the problem with corresponding JUnit tests and suggests an incomplete solution, that relies on caching.
An alternative solution is discussed in #882 to reimplement SWT GTK child tracking in a manner similar to that of Mac OS implementation, so this proposal should not be merged, if anyone is ready to implement a better and more complete solution.