gpt4 book ai didi

java - GTK 2/3 是否支持高效的虚拟表?

转载 作者:行者123 更新时间:2023-11-29 04:31:09 25 4
gpt4 key购买 nike

我们正在使用提供虚拟 表的 SWT 开发 Java 应用程序。允许在 100 和 10M 之间切换表格行数的测试代码在 Windows 和 OSX 上运行不到 100 毫秒,但在 Ubuntu 16.04 上需要几秒钟。现在我们想知道这是 SWT 的 GTK 实现的缺点还是 GTK 本身的缺点?在后一种情况下,GTK 2 和 GTK 3 之间有区别吗?

最佳答案

TLDR:不幸的是,GTK 的 GtkTreeView似乎根本不支持虚拟模式,而且它的实现方式对于大量项目来说效率非常低。 SWT 选择使用 GtkTreeView 实现 Table 并引入了进一步的性能问题。

SWT Table.setItemCount()

Table.setItemCount() 的来源:

  • 存储库:http://git.eclipse.org/gitroot/platform/eclipse.platform.swt.git
  • 源文件:eclipse.platform.swt\bundles\org.eclipse.swt\Eclipse SWT\gtk\org\eclipse\swt\widgets\Table.java
  • 查找:public void setItemCount (int count) {

您会看到,即使在 VIRTUAL 模式下,setItemCount 也会使用 OS.gtk_list_store_append() 分配所有项目,一次分配一个项目:

for (int i=itemCount; i<count; i++) {
OS.gtk_list_store_append (modelHandle, iter);
}

SWT OS.gtk_list_store_append

OS.gtk_list_store_append 的来源:

  • 存储库:http://git.eclipse.org/gitroot/platform/eclipse.platform.swt.git
  • 源文件:eclipse.platform.swt\bundles\org.eclipse.swt\Eclipse SWT\gtk\org\eclipse\swt\widgets\Table.java
  • 查找:public static final void gtk_list_store_append(long/*int*/list_store, long/*int*/iter) {

在这里,对于每个项目,都会获取和释放锁,并调用本地方法。我想他们至少应该通过一次本地调用分配所有项目。

public static final void gtk_list_store_append(long /*int*/ list_store, long /*int*/ iter) {
lock.lock();
try {
_gtk_list_store_append(list_store, iter);
} finally {
lock.unlock();
}
}

GTK gtk_list_store_append

  • 存储库:git://git.gnome.org/gtk+
  • 源文件:gtk/gtkliststore.c
  • 查找:gtk_list_store_append (GtkListStore *list_store,

它仅调用 gtk_list_store_insert(list_store, iter, -1)

GTK gtk_list_store_insert

  • 存储库:git://git.gnome.org/gtk+
  • 源文件:gtk/gtkliststore.c
  • 查找:gtk_list_store_insert (GtkListStore *list_store,

关键操作是 g_sequence_insert_before 插入 gsequence , 这是一棵平衡树。

void
gtk_list_store_insert (GtkListStore *list_store,
GtkTreeIter *iter,
gint position)
{
GtkListStorePrivate *priv;
GtkTreePath *path;
GSequence *seq;
GSequenceIter *ptr;
gint length;

g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter != NULL);

priv = list_store->priv;

priv->columns_dirty = TRUE;

seq = priv->seq;

length = g_sequence_get_length (seq);
if (position > length || position < 0)
position = length;

ptr = g_sequence_get_iter_at_pos (seq, position);
ptr = g_sequence_insert_before (ptr, NULL);

iter->stamp = priv->stamp;
iter->user_data = ptr;

g_assert (iter_is_valid (iter, list_store));

priv->length++;

path = gtk_tree_path_new ();
gtk_tree_path_append_index (path, position);
gtk_tree_model_row_inserted (GTK_TREE_MODEL (list_store), path, iter);
gtk_tree_path_free (path);
}

不幸的是,这个函数做了很多在批量插入期间不需要的事情,例如它每次都计算序列的长度(具有非平凡的时间复杂度),将索引转换为迭代器, 触发树的更新通知等。

我进行了搜索,但没有找到任何适合批量插入的内容。

Windows 实现

Table 的 Windows 实现使用操作系统提供的 ListView 控件,该控件在虚拟模式下有效实现(参见 LVS_OWNERDATA)

另请参阅:Eclipse Bug 236863

关于java - GTK 2/3 是否支持高效的虚拟表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43754901/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com