2

在我的应用程序中,我需要将Glib GHashTable 实例保存到磁盘中,然后再加载到内存中。但我找不到任何直接转储实例的方法。

一种选择是不直接保存 GHashTable,而是一个接一个地保存条目。加载时,逐一加载条目,并插入到新的哈希表中。但是我发现执行这个操作需要很多时间:

g_hash_table_insert(hash, (gpointer) (mer_v), (gpointer) m);

加载 6000 万个条目大约需要 20 分钟。如果我只是加载条目而不执行插入,则只需 10 秒。

那么有没有其他方法可以有效地保存 GHashTable 呢?谢谢

=======================

更新:

我的哈希表键是 uint64_t。此代码运行大约 10 秒:

for (i = 0; i < 60000000; i++) {
    tmp = (uint64_t*) malloc (sizeof(uint64_t));
    *tmp = i;
    g_hash_table_insert(hash, (gpointer) (tmp), (gpointer) tmp);
}

但是这段代码运行了 10 多分钟:

for (i = 0; i < meta->n_kmers; i++) {
    m = g_ptr_array_index(kmer_list, i);
    tmp = (uint64_t*) malloc (sizeof(uint64_t));
    *tmp = m->s;
    g_hash_table_insert(hash, (gpointer) (tmp), (gpointer) tmp);
}

我的大部分输入键m->s都有约 60 位。

4

3 回答 3

3

GHashTable 没有针对该数据集的大小进行优化。您最好编写自己的哈希表。

于 2013-03-27T15:16:02.817 回答
3

您可能应该查看当前对 GIO 和 dconf 私有的 gvdb 代码。gvdb 是一个为通过 mmap() 读取而优化的哈希表:

https://git.gnome.org/browse/glib/tree/gio/gvdb/

它使用 GVariant 以内存高效的二进制表示形式存储数据。该代码在 LGPL v2.1+ 下,因此只能在具有兼容许可证的项目中剪切和粘贴。

于 2013-03-27T19:41:59.153 回答
1

我同意 ebassi(以及 iain 和 unwind)的观点,即 GHashTable 可能不适合您的用例。

SQLite应该可以正常工作,但也有许多非常快速的嵌入式键值存储可用。dbm 的维基百科页面列出了很多。如果我是你,我可能会使用Tokyo CabinetLevelDB,或者(如果你的项目是 GPL 兼容的),Kyoto Cabinet

此外,您可能应该考虑使用切片分配器而不是 malloc 。你仍然会有很长的加载和保存(通过使用嵌入式数据库来消除),但它应该比 malloc 快很多。或者,如果您可以使用 32 位密钥而不是 64 位密钥,则可以只使用GINT_TO_POINTER并加快速度。

于 2013-03-28T22:03:20.957 回答