Open vogella opened 2 years ago
cc @jukzi
i don't have linux
@vogella please surround code blocks with three backticks ```
I already improved performance significantly in https://bugs.eclipse.org/bugs/show_bug.cgi?id=575787#c3 How many items are being added?
I already improved performance significantly in https://bugs.eclipse.org/bugs/show_bug.cgi?id=575787#c3 How many items are being added?
If I open the history view in a debug session and open eclipse.platform.ui I see that org.eclipse.jface.viewers.TableViewer.doSetItemCount(TableViewer.java:231) is called multiple times, the largest value I see it 10001 as count. Adding @tomaswolf (main EGit developer) who might share more on the logic here.
I tested this snippet on my Ubuntu 22.04
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout (new GridLayout (1, true));
Table table = new Table(shell, SWT.VIRTUAL);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
shell.pack();
shell.open();
for (int i = 0; i < 100; i++) {
if ((i % 2) == 0) {
final long start = System.currentTimeMillis();
{
table.setItemCount(10_000);
}
final long end = System.currentTimeMillis();
System.out.println("table.setItemCount: " + (end - start) + " ms");
} else {
final long start = System.currentTimeMillis();
{
table.setItemCount(0);
}
final long end = System.currentTimeMillis();
System.out.println("table.removeAll: " + (end - start) + " ms");
}
}
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
and the results are
table.setItemCount: 48 ms
table.removeAll: 71 ms
This looks fast enough to me. So I don't think that the problem is in SWT, at least not with what I currently know.
@SyntevoAlex : I assume the problem is when the tree items are really created / removed before setItemCount()
is called. The snippet is fast because it doesn't crate/remove any item.
OK, here's a more realistic snippet:
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout (new GridLayout (1, true));
Table table = new Table(shell, SWT.VIRTUAL);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final int[] iteration = new int[1];
table.addListener(SWT.SetData, event -> ((Item)event.item).setText("Row:" + iteration[0] + ":" + event.index));
Runnable runCreateItems = () -> {
iteration[0]++;
// setItemCount()
{
final long start = System.currentTimeMillis();
{
table.setItemCount(10_000);
}
final long end = System.currentTimeMillis();
System.out.println("table.setItemCount: " + (end - start) + " ms");
}
// Force items to be cached
{
final long start = System.currentTimeMillis();
{
for (int iItem = 0; iItem < table.getItemCount(); iItem++) {
table.getItem(iItem);
}
}
final long end = System.currentTimeMillis();
System.out.println("table.getItem: " + (end - start) + " ms");
}
};
Runnable runDeleteItems = () -> {
final long start = System.currentTimeMillis();
{
table.setItemCount(0);
}
final long end = System.currentTimeMillis();
System.out.println("table.removeAll: " + (end - start) + " ms");
};
Button btnCreateItems = new Button(shell, 0);
btnCreateItems.setText("Create items");
btnCreateItems.addListener(SWT.Selection, e -> {
runCreateItems.run();
});
Button btnDeleteItems = new Button(shell, 0);
btnDeleteItems.setText("Delete items");
btnDeleteItems.addListener(SWT.Selection, e -> {
runDeleteItems.run();
});
Button btnBoth = new Button(shell, 0);
btnBoth.setText("Do both");
btnBoth.addListener(SWT.Selection, e -> {
runDeleteItems.run();
runCreateItems.run();
});
runCreateItems.run();
shell.setSize(300, 500);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
When I click on Do both
, the first iteration is slow (~2800ms), and since the second, the times are like:
table.removeAll: 157 ms
table.setItemCount: 149 ms
table.getItem: 12 ms
In Java, all time is spent in a single call to gtk_list_store_clear()
.
When native profiling, it looks like this
- 60,96% gtk_list_store_remove
- 60,56% g_signal_emit
- g_signal_emit_valist
- 60,41% signal_emit_unlocked_R
- 60,27% g_closure_invoke
- 60,02% gtk_tree_view_row_deleted.lto_priv.0
- 41,05% gtk_tree_view_real_set_cursor.lto_priv.0
- 34,59% _gtk_tree_view_accessible_add_state
- 34,55% create_cell.lto_priv.0
- 13,34% set_cell_data.lto_priv.0
- 12,70% gtk_cell_area_apply_attributes
- 12,57% g_signal_emit
- g_signal_emit_valist
- 12,30% _gtk_marshal_VOID__OBJECT_BOXED_BOOLEAN_BOOLEANv
- 11,85% gtk_cell_area_box_apply_attributes
- 11,65% gtk_cell_area_real_apply_attributes
- 10,83% g_hash_table_foreach
- 10,69% apply_cell_attributes
+ 5,08% g_object_set_property
- 1,76% fn19_5
- 1,70% callback
+ 0,95% jni_CallLongMethodV
+ 1,22% g_object_get
+ 1,09% g_object_thaw_notify
+ 6,74% g_object_notify
+ 5,76% gtk_container_cell_accessible_update_cache
+ 5,57% gtk_renderer_cell_accessible_new
+ 0,94% gtk_accessible_set_widget
+ 0,84% gtk_container_cell_accessible_new
+ 5,59% _gtk_tree_selection_internal_select_node
0,56% g_signal_emit_by_name
- 15,61% _gtk_tree_view_accessible_remove
- 13,88% iter_remove_or_steal
- 13,84% cell_info_free
- 5,34% g_object_unref
+ 1,85% 0x7fb2e007b122
+ 0,87% gtk_text_cell_accessible_finalize
0,60% g_object_notify_queue_freeze.lto_priv.0
+ 3,57% gtk_container_cell_accessible_remove_child
+ 3,48% gtk_accessible_set_widget
+ 1,21% g_object_notify
+ 1,51% g_signal_emit_by_name
+ 1,35% gtk_widget_queue_resize
That is, it spends a lot of time reacting to row-deleted
events. It's also related to gtk_tree_view_accessible
.
I can't explain why it becomes faster after first iteration. Unfortunately I can't spend time debugging it further.
Environment:
Eclipse SDK Version: 2022-06 (4.25) Build id: I20220612-1800 OS: Linux, v.5.15.0-37-generic, x86_64 / gtk 3.24.33, WebKit 2.36.3 Java vendor: Eclipse Adoptium Java runtime version: 17.0.3+7 Java version: 17.0.3
I see long UI freezes coming from the Git History view with regards to Table.setItemCount. Looks like a lot is happening in this method, like removing all items, etc. Can this be improved?
Method code:
Stack Trace